]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 11 May 2007 23:05:43 +0000 (16:05 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 11 May 2007 23:05:43 +0000 (16:05 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog:
  [WATCHDOG] iTCO_wdt.c - fix ACPI Base register

362 files changed:
Documentation/feature-removal-schedule.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/Bt87x.txt
Documentation/video4linux/CARDLIST.saa7134
Documentation/video4linux/sn9c102.txt
MAINTAINERS
arch/i386/kernel/verify_cpu.S
arch/ia64/Kconfig
arch/ia64/hp/common/hwsw_iommu.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/err_inject.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/kprobes.c
arch/ia64/kernel/machvec.c
arch/ia64/kernel/mca.c
arch/ia64/mm/contig.c
arch/ia64/mm/discontig.c
arch/ia64/mm/init.c
arch/ia64/sn/kernel/io_common.c
arch/ia64/sn/kernel/xpc_partition.c
arch/ia64/sn/kernel/xpnet.c
arch/x86_64/kernel/aperture.c
arch/x86_64/kernel/bugs.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/setup.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata.h
drivers/ata/pata_ali.c
drivers/ata/pata_amd.c
drivers/ata/pata_artop.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_cmd640.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5520.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cypress.c
drivers/ata/pata_efar.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_hpt3x3.c
drivers/ata/pata_it8213.c
drivers/ata/pata_it821x.c
drivers/ata/pata_ixp4xx_cf.c
drivers/ata/pata_jmicron.c
drivers/ata/pata_marvell.c
drivers/ata/pata_mpc52xx.c
drivers/ata/pata_mpiix.c
drivers/ata/pata_netcell.c
drivers/ata/pata_ns87410.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_opti.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_platform.c
drivers/ata/pata_radisys.c
drivers/ata/pata_rz1000.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_scc.c
drivers/ata/pata_serverworks.c
drivers/ata/pata_sil680.c
drivers/ata/pata_sis.c
drivers/ata/pata_sl82c105.c
drivers/ata/pata_triflex.c
drivers/ata/pata_via.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_nv.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sis.h
drivers/atm/Kconfig
drivers/char/agp/amd64-agp.c
drivers/char/snsc_event.c
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/dvb/Kconfig
drivers/media/dvb/dvb-core/Kconfig
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/m920x.c
drivers/media/dvb/dvb-usb/m920x.h
drivers/media/dvb/dvb-usb/vp702x-fe.c
drivers/media/dvb/pluto2/pluto2.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-core.c
drivers/media/radio/Kconfig
drivers/media/radio/dsbr100.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/Kconfig
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/cx88/cx88-vp3054-i2c.h
drivers/media/video/em28xx/Kconfig
drivers/media/video/et61x251/Kconfig
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/pvrusb2/Kconfig
drivers/media/video/pvrusb2/pvrusb2-encoder.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/pwc/Kconfig
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sn9c102/Kconfig
drivers/media/video/sn9c102/sn9c102.h
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/sn9c102/sn9c102_devtable.h
drivers/media/video/sn9c102/sn9c102_hv7131d.c
drivers/media/video/sn9c102/sn9c102_hv7131r.c
drivers/media/video/sn9c102/sn9c102_mi0343.c
drivers/media/video/sn9c102/sn9c102_mi0360.c
drivers/media/video/sn9c102/sn9c102_ov7630.c
drivers/media/video/sn9c102/sn9c102_ov7660.c
drivers/media/video/sn9c102/sn9c102_pas106b.c
drivers/media/video/sn9c102/sn9c102_pas202bcb.c
drivers/media/video/sn9c102/sn9c102_sensor.h
drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
drivers/media/video/sn9c102/sn9c102_tas5110d.c
drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
drivers/media/video/usbvideo/Kconfig
drivers/media/video/usbvision/Kconfig
drivers/media/video/v4l1-compat.c
drivers/media/video/video-buf.c
drivers/media/video/videodev.c
drivers/media/video/zc0301/Kconfig
drivers/net/Kconfig
drivers/net/mlx4/eq.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/pcmcia/Kconfig
drivers/net/phy/Kconfig
drivers/net/phy/davicom.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/spider_net.c
drivers/net/wan/Kconfig
drivers/net/wireless/libertas/Makefile
drivers/net/wireless/libertas/README
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/fw.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/if_usb.h
drivers/net/wireless/libertas/ioctl.c
drivers/net/wireless/libertas/join.c
drivers/net/wireless/libertas/join.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/scan.h
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/version.h
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas/wext.h
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/msi.c
drivers/pci/quirks.c
include/asm-ia64/irq.h
include/asm-ia64/kprobes.h
include/asm-ia64/pgalloc.h
include/asm-ia64/unistd.h
include/linux/i2c-id.h
include/linux/libata.h
include/linux/pci_ids.h
include/media/saa7146.h
include/media/saa7146_vv.h
include/sound/ak4114.h
include/sound/mpu401.h
include/sound/pcm.h
include/sound/version.h
kernel/irq/proc.c
sound/aoa/codecs/snd-aoa-codec-onyx.c
sound/aoa/codecs/snd-aoa-codec-tas.c
sound/aoa/soundbus/core.c
sound/aoa/soundbus/i2sbus/i2sbus-core.c
sound/aoa/soundbus/soundbus.h
sound/core/pcm_native.c
sound/core/rtctimer.c
sound/drivers/mpu401/mpu401.c
sound/drivers/mpu401/mpu401_uart.c
sound/drivers/mts64.c
sound/drivers/portman2x4.c
sound/drivers/vx/vx_hwdep.c
sound/i2c/other/ak4114.c
sound/isa/Kconfig
sound/isa/ad1816a/ad1816a.c
sound/isa/ad1848/ad1848.c
sound/isa/adlib.c
sound/isa/cmi8330.c
sound/isa/cs423x/cs4231.c
sound/isa/cs423x/cs4231_lib.c
sound/isa/cs423x/cs4236.c
sound/isa/es1688/es1688.c
sound/isa/es18xx.c
sound/isa/gus/gusclassic.c
sound/isa/gus/gusextreme.c
sound/isa/gus/gusmax.c
sound/isa/gus/interwave.c
sound/isa/opl3sa2.c
sound/isa/opti9xx/miro.c
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/sb/sb16.c
sound/isa/sb/sb16_csp.c
sound/isa/sb/sb8.c
sound/isa/sgalaxy.c
sound/isa/sscape.c
sound/isa/wavefront/wavefront.c
sound/isa/wavefront/wavefront_fx.c
sound/pci/Kconfig
sound/pci/ac97/Makefile
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_local.h
sound/pci/ac97/ac97_patch.c
sound/pci/ac97/ac97_patch.h
sound/pci/ac97/ac97_pcm.c
sound/pci/ali5451/ali5451.c
sound/pci/au88x0/au88x0_sb.h [deleted file]
sound/pci/azt3328.c
sound/pci/azt3328.h
sound/pci/bt87x.c
sound/pci/ca0106/ca0106_main.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/imgs/cwcemb80.h [deleted file]
sound/pci/echoaudio/darla20.c
sound/pci/echoaudio/darla24.c
sound/pci/echoaudio/echo3g.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/echoaudio_3g.c
sound/pci/echoaudio/gina20.c
sound/pci/echoaudio/gina24.c
sound/pci/echoaudio/indigo.c
sound/pci/echoaudio/indigodj.c
sound/pci/echoaudio/indigoio.c
sound/pci/echoaudio/layla20.c
sound/pci/echoaudio/layla24.c
sound/pci/echoaudio/mia.c
sound/pci/echoaudio/mona.c
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/p16v.c
sound/pci/ens1370.c
sound/pci/es1968.c
sound/pci/hda/Makefile
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_local.h
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_atihdmi.c
sound/pci/hda/patch_cmedia.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/ice1712/amp.c
sound/pci/ice1712/amp.h
sound/pci/ice1712/aureon.c
sound/pci/ice1712/aureon.h
sound/pci/ice1712/delta.c
sound/pci/ice1712/delta.h
sound/pci/ice1712/ews.c
sound/pci/ice1712/ews.h
sound/pci/ice1712/hoontech.c
sound/pci/ice1712/hoontech.h
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1712.h
sound/pci/ice1712/ice1724.c
sound/pci/ice1712/juli.c
sound/pci/ice1712/juli.h
sound/pci/ice1712/phase.c
sound/pci/ice1712/phase.h
sound/pci/ice1712/pontis.c
sound/pci/ice1712/pontis.h
sound/pci/ice1712/prodigy192.c
sound/pci/ice1712/prodigy192.h
sound/pci/ice1712/revo.c
sound/pci/ice1712/revo.h
sound/pci/ice1712/vt1720_mobo.c
sound/pci/ice1712/vt1720_mobo.h
sound/pci/ice1712/wtm.c
sound/pci/intel8x0.c
sound/pci/korg1212/korg1212.c
sound/pci/maestro3.c
sound/pci/mixart/mixart_hwdep.c
sound/pci/pcxhr/pcxhr.c
sound/pci/pcxhr/pcxhr_hwdep.c
sound/pci/riptide/riptide.c
sound/pci/rme32.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/pci/trident/trident_main.c
sound/pci/ymfpci/ymfpci_main.c
sound/pcmcia/vx/vxpocket.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/at91/Kconfig
sound/soc/at91/Makefile
sound/soc/at91/at91-i2s.c [deleted file]
sound/soc/at91/at91-i2s.h [deleted file]
sound/soc/at91/at91-ssc.c [new file with mode: 0644]
sound/soc/at91/at91-ssc.h [new file with mode: 0644]
sound/soc/at91/eti_b1_wm8731.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ac97.c
sound/soc/codecs/ac97.h
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c [new file with mode: 0644]
sound/soc/codecs/wm8753.h [new file with mode: 0644]
sound/soc/codecs/wm9712.c
sound/soc/pxa/Kconfig
sound/soc/s3c24xx/Kconfig [new file with mode: 0644]
sound/soc/s3c24xx/Makefile [new file with mode: 0644]
sound/soc/s3c24xx/s3c24xx-i2s.c [new file with mode: 0644]
sound/soc/s3c24xx/s3c24xx-i2s.h [new file with mode: 0644]
sound/soc/s3c24xx/s3c24xx-pcm.c [new file with mode: 0644]
sound/soc/s3c24xx/s3c24xx-pcm.h [new file with mode: 0644]
sound/soc/soc-dapm.c
sound/sparc/cs4231.c
sound/usb/Kconfig
sound/usb/Makefile
sound/usb/caiaq/Makefile [new file with mode: 0644]
sound/usb/caiaq/caiaq-audio.c [new file with mode: 0644]
sound/usb/caiaq/caiaq-audio.h [new file with mode: 0644]
sound/usb/caiaq/caiaq-device.c [new file with mode: 0644]
sound/usb/caiaq/caiaq-device.h [new file with mode: 0644]
sound/usb/caiaq/caiaq-input.c [new file with mode: 0644]
sound/usb/caiaq/caiaq-input.h [new file with mode: 0644]
sound/usb/caiaq/caiaq-midi.c [new file with mode: 0644]
sound/usb/caiaq/caiaq-midi.h [new file with mode: 0644]
sound/usb/usbaudio.c
sound/usb/usbmidi.c
sound/usb/usbquirks.h

index c6322c760348f243a30c61ffc22bd63259c3116a..498ff31f3aa1d57053f71c9ad8f91a4d67ddf16c 100644 (file)
@@ -328,3 +328,22 @@ Who:   Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
+What: libata.spindown_compat module parameter
+When: Dec 2008
+Why:  halt(8) synchronizes caches for and spins down libata disks
+      because libata didn't use to spin down disk on system halt
+      (only synchronized caches).
+      Spin down on system halt is now implemented and can be tested
+      using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop.
+      Because issuing spin down command to an already spun down disk
+      makes some disks spin up just to spin down again, the old
+      behavior needs to be maintained till userspace tool is updated
+      to check the sysfs node and not to spin down disks with the
+      node set to one.
+      This module parameter is to give userspace tool the time to
+      get updated and should be removed after userspace is
+      reasonably updated.
+Who:  Tejun Heo <htejun@gmail.com>
+
+---------------------------
+
index 73e9a174b6427853b073bf4143e88e9f6e014a0f..57b878cc393c20ebd04c7713f83e3c249ae83db3 100644 (file)
@@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          6stack-dig    6-jack digital with SPDIF I/O
          arima         Arima W820Di1
          macpro        MacPro support
+         w2jc          ASUS W2JC
          auto          auto-config reading BIOS (default)
 
        ALC883/888
@@ -852,6 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          3stack-dig    3-jack with SPDIF OUT
          6stack-dig    6-jack with SPDIF OUT
          3stack-660    3-jack (for ALC660VD)
+         lenovo        Lenovo 3000 C200
          auto          auto-config reading BIOS (default)
 
        CMI9880
@@ -909,6 +911,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          macbook       Intel Mac Book
          macbook-pro-v1 Intel Mac Book Pro 1st generation
          macbook-pro   Intel Mac Book Pro 2nd generation
+         imac-intel    Intel iMac
 
        STAC9202/9250/9251
          ref           Reference board, base config
@@ -924,6 +927,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          vaio          Setup for VAIO FE550G/SZ110
          vaio-ar Setup for VAIO AR
 
+    The model name "genric" is treated as a special case.  When this
+    model is given, the driver uses the generic codec parser without
+    "codec-patch".  It's sometimes good for testing and debugging.
+
     If the default configuration doesn't work and one of the above
     matches with your device, report it together with the PCI
     subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
@@ -1278,6 +1285,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     port       - port number or -1 (disable)
     irq                - IRQ number or -1 (disable)
     pnp                - PnP detection - 0 = disable, 1 = enable (default)
+    uart_enter - Issue UART_ENTER command at open - bool, default = on
 
     This module supports multiple devices and PnP.
     
@@ -1692,6 +1700,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
     This module supports multiple devices, autoprobe and hotplugging.
 
+  Module snd-usb-caiaq
+  --------------------
+
+    Module for caiaq UB audio interfaces,
+           * Native Instruments RigKontrol2
+           * Native Instruments Kore Controller
+           * Native Instruments Audio Kontrol 1
+           * Native Instruments Audio 8 DJ
+
+    This module supports multiple devices, autoprobe and hotplugging.
+
   Module snd-usb-usx2y
   --------------------
 
@@ -2046,4 +2065,4 @@ Links and Addresses
        https://bugtrack.alsa-project.org/bugs/
 
   ALSA Developers ML
-       mailto:alsa-devel@lists.sourceforge.net
+       mailto:alsa-devel@alsa-project.org
index 11edb2fd2a5a2b7b998cbbb6fe26b073a29b028d..f158cde8b065a7c3632b53863a53d795c328110f 100644 (file)
@@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with
 other values than the default 32000 (often it's 44100 or 64000).
 
 If you have an unknown card, please mail the ID and board name to
-<alsa-devel@lists.sf.net>, regardless of whether audio capture works or
-not, so that future versions of this driver know about your card.
+<alsa-devel@alsa-project.org>, regardless of whether audio capture works
+or not, so that future versions of this driver know about your card.
 
 
 Audio modes
index d7bb2e2e4d9b12cc3e5877033f375c2bd4d09b25..712e8c8333cc90153f37be879adee04ec89b73ea 100644 (file)
@@ -52,7 +52,7 @@
  51 -> ProVideo PV952                           [1540:9524]
  52 -> AverMedia AverTV/305                     [1461:2108]
  53 -> ASUS TV-FM 7135                          [1043:4845]
- 54 -> LifeView FlyTV Platinum FM / Gold        [5168:0214,1489:0214,5168:0304]
+ 54 -> LifeView FlyTV Platinum FM / Gold        [5168:0214,5168:5214,1489:0214,5168:0304]
  55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
 110 -> Avermedia M102                           [1461:f31e]
 111 -> ASUS P7131 4871                          [1043:4871]
 112 -> ASUSTeK P7131 Hybrid                     [1043:4876]
+113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6]
+114 -> KWorld DVB-T 210                         [17de:7250]
+115 -> Sabrent PCMCIA TV-PCB05                  [0919:2003]
index 5fe0ad7dfc20db7b9fc5093a834572a7bec248dd..279717c96f63c6a0a951d395307d7aa7ebf94c32 100644 (file)
@@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers:
 
 Vendor ID  Product ID
 ---------  ----------
+0x0458     0x7025
+0x045e     0x00f5
+0x045e     0x00f7
 0x0471     0x0327
 0x0471     0x0328
 0x0c45     0x6001
@@ -432,7 +435,7 @@ Image sensor / SN9C1xx bridge      | SN9C10[12]  SN9C103  SN9C105  SN9C120
 HV7131D    Hynix Semiconductor     | Yes         No       No       No
 HV7131R    Hynix Semiconductor     | No          Yes      Yes      Yes
 MI-0343    Micron Technology       | Yes         No       No       No
-MI-0360    Micron Technology       | No          Yes      No       No
+MI-0360    Micron Technology       | No          Yes      Yes      Yes
 OV7630     OmniVision Technologies | Yes         Yes      No       No
 OV7660     OmniVision Technologies | No          No       Yes      Yes
 PAS106B    PixArt Imaging          | Yes         No       No       No
@@ -478,13 +481,12 @@ scaling factor is restored to 1.
 This driver supports two different video formats: the first one is the "8-bit
 Sequential Bayer" format and can be used to obtain uncompressed video data
 from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without frame headers not related to the
-compressed data). The compression quality may vary from 0 to 1 and can be
-selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
-ioctl's. For maximum flexibility, both the default active video format and the
-default compression quality depend on how the image sensor being used is
-initialized (as described in the documentation of the API for the image sensors
-supplied by this driver).
+either "raw" compressed video data (without frame headers not related to the
+compressed data) or standard JPEG (with frame headers). The compression quality
+may vary from 0 to 1 and can be selected or queried thanks to the
+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
+both the default active video format and the default compression quality
+depend on how the image sensor being used is initialized.
 
 
 11. Video frame formats [1]
index bd558ac5bb73ced7de418089a9ae499732cfe3c9..975f263f5c21a165ebaf5fe7e22e38e9ec26a8f6 100644 (file)
@@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER
 P:     Johannes Berg
 M:     johannes@sipsolutions.net
 L:     linuxppc-dev@ozlabs.org
-L:     alsa-devel@alsa-project.org
+L:     alsa-devel@alsa-project.org (subscribers-only)
 S:     Maintained
 
 APM DRIVER
@@ -3239,13 +3239,13 @@ S:      Maintained
 SOUND
 P:     Jaroslav Kysela
 M:     perex@suse.cz
-L:     alsa-devel@alsa-project.org
+L:     alsa-devel@alsa-project.org (subscribers-only)
 S:     Maintained
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
 P:     Liam Girdwood
 M:     liam.girdwood@wolfsonmicro.com
-L:     alsa-devel@alsa-project.org
+L:     alsa-devel@alsa-project.org (subscribers-only)
 S:     Supported
 
 SPI SUBSYSTEM
index e51a8695d54ef214c4959494c853622cc51b85b9..b2a9d80b64215a826ab17d03407647d4bf129d29 100644 (file)
@@ -10,7 +10,9 @@ verify_cpu:
 
 #if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
        pushfl
-       orl     $(1<<18),(%esp)         # try setting AC
+       pop     %eax
+       orl     $(1<<18),%eax           # try setting AC
+       push    %eax
        popfl
        pushfl
        popl    %eax
index 6e41471449c034f0cd32265590608fcfe68b604c..de1bff6599690c89d9f4f290edcb167e70d79b82 100644 (file)
@@ -31,6 +31,10 @@ config ZONE_DMA
        def_bool y
        depends on !IA64_SGI_SN2
 
+config QUICKLIST
+       bool
+       default y
+
 config MMU
        bool
        default y
index 2153bcacbe6c9d29818608521293d08842594859..94e57109fad658d060542aea2ed9f51bd1d230db 100644 (file)
@@ -63,7 +63,7 @@ use_swiotlb (struct device *dev)
        return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
 }
 
-void
+void __init
 hwsw_init (void)
 {
        /* default to a smallish 2MB sw I/O TLB */
index b50bf208678ea6c981f3e1b4e439b69e80887e4f..144b056282af0c06762fc1060cca5c219085523b 100644 (file)
@@ -1583,5 +1583,7 @@ sys_call_table:
        data8 sys_vmsplice
        data8 sys_ni_syscall                    // reserved for move_pages
        data8 sys_getcpu
+       data8 sys_epoll_pwait                   // 1305
+       data8 sys_utimensat
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
index 6a49600cf337f5e468e857ccce5088f12917bfe8..b642648cc2acdbd7a1548d8d76685fec568cced7 100644 (file)
@@ -291,5 +291,5 @@ module_init(err_inject_init);
 module_exit(err_inject_exit);
 
 MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
-MODULE_DESCRIPTION("MC error injection kenrel sysfs interface");
+MODULE_DESCRIPTION("MC error injection kernel sysfs interface");
 MODULE_LICENSE("GPL");
index ce49c85c928f5fe44f52501c86211b11926c89d8..b4c239685d2eb8f0072d2510573d027ab867d1c3 100644 (file)
@@ -104,6 +104,17 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
                irq_redir[irq] = (char) (redir & 0xff);
        }
 }
+
+bool is_affinity_mask_valid(cpumask_t cpumask)
+{
+       if (ia64_platform_is("sn2")) {
+               /* Only allow one CPU to be specified in the smp_affinity mask */
+               if (cpus_weight(cpumask) != 1)
+                       return false;
+       }
+       return true;
+}
+
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
index 4f5fd0960ba7c0c7e1c44e0c358edff198e947f0..72e593e940531dc136af5334f83d29f00235ff31 100644 (file)
@@ -370,14 +370,18 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
 
 static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kcb->prev_kprobe.kp = kprobe_running();
-       kcb->prev_kprobe.status = kcb->kprobe_status;
+       unsigned int i;
+       i = atomic_add_return(1, &kcb->prev_kprobe_index);
+       kcb->prev_kprobe[i-1].kp = kprobe_running();
+       kcb->prev_kprobe[i-1].status = kcb->kprobe_status;
 }
 
 static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
-       kcb->kprobe_status = kcb->prev_kprobe.status;
+       unsigned int i;
+       i = atomic_sub_return(1, &kcb->prev_kprobe_index);
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe[i].kp;
+       kcb->kprobe_status = kcb->prev_kprobe[i].status;
 }
 
 static void __kprobes set_current_kprobe(struct kprobe *p,
index 9620822270a6e122d00c48cc5bb2acb89b313e10..13df337508e7fe5f6b626ff66735026469acb1b3 100644 (file)
@@ -35,7 +35,7 @@ lookup_machvec (const char *name)
        return 0;
 }
 
-void
+void __init
 machvec_init (const char *name)
 {
        struct ia64_machine_vector *mv;
index f8ae709de0b5341e48abaaf13ac1bd011dd98ee0..26814de6c29ace5955dc65b3b0eac36b97f36e69 100644 (file)
@@ -118,7 +118,9 @@ static ia64_mc_info_t               ia64_mc_info;
 #define CPE_HISTORY_LENGTH    5
 #define CMC_HISTORY_LENGTH    5
 
+#ifdef CONFIG_ACPI
 static struct timer_list cpe_poll_timer;
+#endif
 static struct timer_list cmc_poll_timer;
 /*
  * This variable tells whether we are currently in polling mode.
index 44ce5ed9444ca255e2df50971608db16acaf81c2..7ac8592a35b6fd0a8550de87fedec681496a9d7b 100644 (file)
@@ -88,7 +88,7 @@ void show_mem(void)
        printk(KERN_INFO "%d pages shared\n", total_shared);
        printk(KERN_INFO "%d pages swap cached\n", total_cached);
        printk(KERN_INFO "Total of %ld pages in page table cache\n",
-              pgtable_quicklist_total_size());
+              quicklist_total_size());
        printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
 }
 
index 94844442812a98e31ddaf083dbb68fd74a9b0d55..38085ac183380af17b1a805151c10699a89385fb 100644 (file)
@@ -561,7 +561,7 @@ void show_mem(void)
        printk(KERN_INFO "%d pages shared\n", total_shared);
        printk(KERN_INFO "%d pages swap cached\n", total_cached);
        printk(KERN_INFO "Total of %ld pages in page table cache\n",
-              pgtable_quicklist_total_size());
+              quicklist_total_size());
        printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
 }
 
index cffb1e8325e8e226fdde5e996f33aad425bf6006..c14abefabafae6ed8932d9231092a8b55aed3a1d 100644 (file)
@@ -39,9 +39,6 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-DEFINE_PER_CPU(unsigned long *, __pgtable_quicklist);
-DEFINE_PER_CPU(long, __pgtable_quicklist_size);
-
 extern void ia64_tlb_init (void);
 
 unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
@@ -56,54 +53,6 @@ EXPORT_SYMBOL(vmem_map);
 struct page *zero_page_memmap_ptr;     /* map entry for zero page */
 EXPORT_SYMBOL(zero_page_memmap_ptr);
 
-#define MIN_PGT_PAGES                  25UL
-#define MAX_PGT_FREES_PER_PASS         16L
-#define PGT_FRACTION_OF_NODE_MEM       16
-
-static inline long
-max_pgt_pages(void)
-{
-       u64 node_free_pages, max_pgt_pages;
-
-#ifndef        CONFIG_NUMA
-       node_free_pages = nr_free_pages();
-#else
-       node_free_pages = node_page_state(numa_node_id(), NR_FREE_PAGES);
-#endif
-       max_pgt_pages = node_free_pages / PGT_FRACTION_OF_NODE_MEM;
-       max_pgt_pages = max(max_pgt_pages, MIN_PGT_PAGES);
-       return max_pgt_pages;
-}
-
-static inline long
-min_pages_to_free(void)
-{
-       long pages_to_free;
-
-       pages_to_free = pgtable_quicklist_size - max_pgt_pages();
-       pages_to_free = min(pages_to_free, MAX_PGT_FREES_PER_PASS);
-       return pages_to_free;
-}
-
-void
-check_pgt_cache(void)
-{
-       long pages_to_free;
-
-       if (unlikely(pgtable_quicklist_size <= MIN_PGT_PAGES))
-               return;
-
-       preempt_disable();
-       while (unlikely((pages_to_free = min_pages_to_free()) > 0)) {
-               while (pages_to_free--) {
-                       free_page((unsigned long)pgtable_quicklist_alloc());
-               }
-               preempt_enable();
-               preempt_disable();
-       }
-       preempt_enable();
-}
-
 void
 lazy_mmu_prot_update (pte_t pte)
 {
index d48bcd83253c28073050377cbd5f937882a3f6a5..7ed72d3faf73047130cdc042e8da9a02b3e6ed36 100644 (file)
@@ -364,7 +364,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev)
 
        element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
        if (!element) {
-               dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
+               dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__);
                return;
        }
        element->sysdata = SN_PCIDEV_INFO(dev);
index 57c723f5cba404f5cda5fbefd6a370c97bc328df..7ba403232cb8321516bbbceb0cb8eeb841a467d8 100644 (file)
@@ -574,7 +574,7 @@ xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
                u64 remote_vars_pa, struct xpc_vars *remote_vars)
 {
        part->remote_rp_version = remote_rp_version;
-       dev_dbg(xpc_part, "  remote_rp_version = 0x%016lx\n",
+       dev_dbg(xpc_part, "  remote_rp_version = 0x%016x\n",
                part->remote_rp_version);
 
        part->remote_rp_stamp = *remote_rp_stamp;
index 88fad85ceeff5b6f2ce18c39f05b5f3581bbedb2..da7213530972820fbc34bdc37b0eb051137e991a 100644 (file)
@@ -343,8 +343,8 @@ xpnet_dev_open(struct net_device *dev)
        enum xpc_retval ret;
 
 
-       dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, "
-               "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
+       dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
+               "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
                XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS,
                XPNET_MAX_IDLE_KTHREADS);
 
index a52af58205921b37b45e33b137f706dfa6bb3bc5..a3d450d6c15b5219443efc735457a1c7f326ad1d 100644 (file)
@@ -86,7 +86,7 @@ static int __init aperture_valid(u64 aper_base, u32 aper_size)
                printk("Aperture too small (%d MB)\n", aper_size>>20);
                return 0;
        }
-       if (aper_base + aper_size >= 0xffffffff) { 
+       if (aper_base + aper_size > 0x100000000UL) {
                printk("Aperture beyond 4GB. Ignoring.\n");
                return 0; 
        }
index 12b585b5345d4a8abb97e0ae2a1f384b1d4bc33e..c141e7a7ff5547760ca3a9f60dc7e53d79c9071f 100644 (file)
@@ -13,6 +13,7 @@
 void __init check_bugs(void)
 {
        identify_cpu(&boot_cpu_data);
+       mtrr_bp_init();
 #if !defined(CONFIG_SMP)
        printk("CPU: ");
        print_cpu_info(&boot_cpu_data);
index 373ef66ca1dcff5cb2a43ee19219189850695fba..ae091cdc1a4de3764389c5a18e36adb42b9ddfcc 100644 (file)
@@ -476,7 +476,7 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
        aper_base <<= 25;
 
        aper_size = (32 * 1024 * 1024) << aper_order; 
-       if (aper_base + aper_size >= 0xffffffff || !aper_size)
+       if (aper_base + aper_size > 0x100000000UL || !aper_size)
                aper_base = 0;
 
        *size = aper_size;
index db51577bda32dfc112566b5551fdc6223ec0f1e3..eb6524f3ac29b00482800421ed615b674ee453de 100644 (file)
@@ -891,9 +891,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_MCE
        mcheck_init(c);
 #endif
-       if (c == &boot_cpu_data)
-               mtrr_bp_init();
-       else
+       if (c != &boot_cpu_data)
                mtrr_ap_init();
 #ifdef CONFIG_NUMA
        numa_add_cpu(smp_processor_id());
index f031b87323308e3131898edecf3be5863e171070..ad1f59c1b3fc2516306695378b2a76128a958783 100644 (file)
@@ -2,11 +2,9 @@
 # SATA/PATA driver configuration
 #
 
-menu "Serial ATA (prod) and Parallel ATA (experimental) drivers"
+menuconfig ATA
+       tristate "Serial ATA (prod) and Parallel ATA (experimental) drivers"
        depends on HAS_IOMEM
-
-config ATA
-       tristate "ATA device support"
        depends on BLOCK
        depends on !(M32R || M68K) || BROKEN
        depends on !SUN4 || BROKEN
@@ -24,6 +22,19 @@ config ATA_NONSTANDARD
        bool
        default n
 
+config ATA_ACPI
+       bool
+       depends on ACPI && PCI
+       default y
+       help
+         This option adds support for ATA-related ACPI objects.
+         These ACPI objects add the ability to retrieve taskfiles
+         from the ACPI BIOS and write them to the disk controller.
+         These objects may be related to performance, security,
+         power management, or other areas.
+         You can disable this at kernel boot time by using the
+         option libata.noacpi=1
+
 config SATA_AHCI
        tristate "AHCI SATA support"
        depends on PCI
@@ -157,19 +168,6 @@ config SATA_INIC162X
        help
          This option enables support for Initio 162x Serial ATA.
 
-config SATA_ACPI
-       bool
-       depends on ACPI && PCI
-       default y
-       help
-         This option adds support for SATA-related ACPI objects.
-         These ACPI objects add the ability to retrieve taskfiles
-         from the ACPI BIOS and write them to the disk controller.
-         These objects may be related to performance, security,
-         power management, or other areas.
-         You can disable this at kernel boot time by using the
-         option libata.noacpi=1
-
 config PATA_ALI
        tristate "ALi PATA support (Experimental)"
        depends on PCI && EXPERIMENTAL
@@ -585,6 +583,4 @@ config PATA_SCC
 
          If unsure, say N.
 
-endif
-endmenu
-
+endif # ATA
index 6f42a0e2812d0c58e0c064a38e33bbdd53a45823..8149c68ac2c71475d9e88d0fc41c0b63ef38323e 100644 (file)
@@ -69,4 +69,4 @@ obj-$(CONFIG_ATA_GENERIC)     += ata_generic.o
 obj-$(CONFIG_PATA_LEGACY)      += pata_legacy.o
 
 libata-objs    := libata-core.o libata-scsi.o libata-sff.o libata-eh.o
-libata-$(CONFIG_SATA_ACPI) += libata-acpi.o
+libata-$(CONFIG_ATA_ACPI)      += libata-acpi.o
index d9617892fc23806d0f8ffdebb200d74c513f8511..1ae443d7ab92223335631a430fc77c948bb7aa8b 100644 (file)
@@ -250,10 +250,6 @@ static struct scsi_host_template ahci_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations ahci_ops = {
@@ -400,6 +396,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 
        /* ATI */
        { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
+       { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */
 
        /* VIA */
        { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
index 92a491ddd03055555c2926ecf16f23c6a4526749..c3d753296bc6a14bde2bbf9c2ce294c855e94ee2 100644 (file)
@@ -54,7 +54,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
-               if (ata_dev_ready(dev)) {
+               if (ata_dev_enabled(dev)) {
                        /* We don't really care */
                        dev->pio_mode = XFER_PIO_0;
                        dev->dma_mode = XFER_MW_DMA_0;
@@ -90,10 +90,6 @@ static struct scsi_host_template generic_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations generic_port_ops = {
@@ -145,7 +141,7 @@ static int all_generic_ide;         /* Set to claim all devices */
 static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        u16 command;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &generic_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -153,7 +149,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
                .udma_mask = 0x3f,
                .port_ops = &generic_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        /* Don't use the generic entry unless instructed to do so */
        if (id->driver_data == 1 && all_generic_ide == 0)
@@ -179,7 +175,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
        if (dev->vendor == PCI_VENDOR_ID_AL)
                ata_pci_clear_simplex(dev);
 
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static struct pci_device_id ata_generic[] = {
index 4a795fdb6a02fa0bf37b150dca27d2d9cd460e88..13b6b1df2ac4f53b0e2a079bccd8025e48463d67 100644 (file)
@@ -275,10 +275,6 @@ static struct scsi_host_template piix_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations piix_pata_ops = {
@@ -1034,7 +1030,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int printed_version;
        struct device *dev = &pdev->dev;
        struct ata_port_info port_info[2];
-       struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
+       const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] };
        struct piix_host_priv *hpriv;
        unsigned long port_flags;
 
@@ -1093,7 +1089,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                port_info[1].mwdma_mask = 0;
                port_info[1].udma_mask = 0;
        }
-       return ata_pci_init_one(pdev, ppinfo, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static int __init piix_init(void)
index cb3eab6e379da2ab9ef8dd6b17021c2d7abaf6ad..ed4138e24b0c3bdeae22b64c12421725ac13ee85 100644 (file)
@@ -270,8 +270,7 @@ out:
 
 /**
  * do_drive_get_GTF - get the drive bootup default taskfile settings
- * @ap: the ata_port for the drive
- * @ix: target ata_device (drive) index
+ * @dev: target ATA device
  * @gtf_length: number of bytes of _GTF data returned at @gtf_address
  * @gtf_address: buffer containing _GTF taskfile arrays
  *
@@ -286,20 +285,19 @@ out:
  * The returned @gtf_length and @gtf_address are only valid if the
  * function return value is 0.
  */
-static int do_drive_get_GTF(struct ata_port *ap, int ix,
-                       unsigned int *gtf_length, unsigned long *gtf_address,
-                       unsigned long *obj_loc)
+static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
+                           unsigned long *gtf_address, unsigned long *obj_loc)
 {
-       acpi_status                     status;
-       acpi_handle                     dev_handle = NULL;
-       acpi_handle                     chan_handle, drive_handle;
-       acpi_integer                    pcidevfn = 0;
-       u32                             dev_adr;
-       struct acpi_buffer              output;
-       union acpi_object               *out_obj;
-       struct device                   *dev = ap->host->dev;
-       struct ata_device               *atadev = &ap->device[ix];
-       int                             err = -ENODEV;
+       struct ata_port *ap = dev->ap;
+       acpi_status status;
+       acpi_handle dev_handle = NULL;
+       acpi_handle chan_handle, drive_handle;
+       acpi_integer pcidevfn = 0;
+       u32 dev_adr;
+       struct acpi_buffer output;
+       union acpi_object *out_obj;
+       struct device *gdev = ap->host->dev;
+       int err = -ENODEV;
 
        *gtf_length = 0;
        *gtf_address = 0UL;
@@ -309,14 +307,14 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                return 0;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
                               __FUNCTION__, ap->port_no);
 
-       if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
+       if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: "
+                       ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: "
                                "ata_dev_present: %d, PORT_DISABLED: %lu\n",
-                               __FUNCTION__, ata_dev_enabled(atadev),
+                               __FUNCTION__, ata_dev_enabled(dev),
                                ap->flags & ATA_FLAG_DISABLED);
                goto out;
        }
@@ -324,19 +322,19 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
        /* Don't continue if device has no _ADR method.
         * _GTF is intended for known motherboard devices. */
        if (!(ap->cbl == ATA_CBL_SATA)) {
-               err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+               err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
                if (err < 0) {
                        if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
+                               ata_dev_printk(dev, KERN_DEBUG,
                                        "%s: pata_get_dev_handle failed (%d)\n",
                                        __FUNCTION__, err);
                        goto out;
                }
        } else {
-               err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+               err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
                if (err < 0) {
                        if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
+                               ata_dev_printk(dev, KERN_DEBUG,
                                        "%s: sata_get_dev_handle failed (%d\n",
                                        __FUNCTION__, err);
                        goto out;
@@ -344,7 +342,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
        }
 
        /* Get this drive's _ADR info. if not already known. */
-       if (!atadev->obj_handle) {
+       if (!dev->obj_handle) {
                if (!(ap->cbl == ATA_CBL_SATA)) {
                        /* get child objects of dev_handle == channel objects,
                         * + _their_ children == drive objects */
@@ -352,7 +350,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                        chan_handle = acpi_get_child(dev_handle,
                                                ap->port_no);
                        if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
+                               ata_dev_printk(dev, KERN_DEBUG,
                                        "%s: chan adr=%d: chan_handle=0x%p\n",
                                        __FUNCTION__, ap->port_no,
                                        chan_handle);
@@ -361,26 +359,26 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
                                goto out;
                        }
                        /* TBD: could also check ACPI object VALID bits */
-                       drive_handle = acpi_get_child(chan_handle, ix);
+                       drive_handle = acpi_get_child(chan_handle, dev->devno);
                        if (!drive_handle) {
                                err = -ENODEV;
                                goto out;
                        }
-                       dev_adr = ix;
-                       atadev->obj_handle = drive_handle;
+                       dev_adr = dev->devno;
+                       dev->obj_handle = drive_handle;
                } else {        /* for SATA mode */
                        dev_adr = SATA_ADR_RSVD;
-                       err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
-                                       ap, atadev, &dev_adr);
+                       err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
+                                       ap, dev, &dev_adr);
                }
                if (err < 0 || dev_adr == SATA_ADR_RSVD ||
-                   !atadev->obj_handle) {
+                   !dev->obj_handle) {
                        if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
+                               ata_dev_printk(dev, KERN_DEBUG,
                                        "%s: get_sata/pata_adr failed: "
                                        "err=%d, dev_adr=%u, obj_handle=0x%p\n",
                                        __FUNCTION__, err, dev_adr,
-                                       atadev->obj_handle);
+                                       dev->obj_handle);
                        goto out;
                }
        }
@@ -391,11 +389,11 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
 
        /* _GTF has no input parameters */
        err = -EIO;
-       status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
+       status = acpi_evaluate_object(dev->obj_handle, "_GTF",
                                        NULL, &output);
        if (ACPI_FAILURE(status)) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
+                       ata_dev_printk(dev, KERN_DEBUG,
                                "%s: Run _GTF error: status = 0x%x\n",
                                __FUNCTION__, status);
                goto out;
@@ -403,7 +401,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
 
        if (!output.length || !output.pointer) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+                       ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
                                "length or ptr is NULL (0x%llx, 0x%p)\n",
                                __FUNCTION__,
                                (unsigned long long)output.length,
@@ -416,7 +414,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
        if (out_obj->type != ACPI_TYPE_BUFFER) {
                kfree(output.pointer);
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+                       ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
                                "error: expected object type of "
                                " ACPI_TYPE_BUFFER, got 0x%x\n",
                                __FUNCTION__, out_obj->type);
@@ -427,7 +425,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
        if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
            out_obj->buffer.length % REGS_PER_GTF) {
                if (ata_msg_drv(ap))
-                       ata_dev_printk(atadev, KERN_ERR,
+                       ata_dev_printk(dev, KERN_ERR,
                                "%s: unexpected GTF length (%d) or addr (0x%p)\n",
                                __FUNCTION__, out_obj->buffer.length,
                                out_obj->buffer.pointer);
@@ -439,7 +437,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
        *gtf_address = (unsigned long)out_obj->buffer.pointer;
        *obj_loc = (unsigned long)out_obj;
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG, "%s: returning "
+               ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
                        "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
                        __FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
        err = 0;
@@ -449,7 +447,7 @@ out:
 
 /**
  * taskfile_load_raw - send taskfile registers to host controller
- * @ap: Port to which output is sent
+ * @dev: target ATA device
  * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
  *
  * Outputs ATA taskfile to standard ATA host controller using MMIO
@@ -466,15 +464,15 @@ out:
  * LOCKING: TBD:
  * Inherited from caller.
  */
-static void taskfile_load_raw(struct ata_port *ap,
-                               struct ata_device *atadev,
-                               const struct taskfile_array *gtf)
+static void taskfile_load_raw(struct ata_device *dev,
+                             const struct taskfile_array *gtf)
 {
+       struct ata_port *ap = dev->ap;
        struct ata_taskfile tf;
        unsigned int err;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
+               ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
                        "%02x %02x %02x %02x %02x %02x %02x\n",
                        __FUNCTION__,
                        gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
@@ -485,7 +483,7 @@ static void taskfile_load_raw(struct ata_port *ap,
            && (gtf->tfa[6] == 0))
                return;
 
-       ata_tf_init(atadev, &tf);
+       ata_tf_init(dev, &tf);
 
        /* convert gtf to tf */
        tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
@@ -498,17 +496,16 @@ static void taskfile_load_raw(struct ata_port *ap,
        tf.device  = gtf->tfa[5];       /* 0x1f6 */
        tf.command = gtf->tfa[6];       /* 0x1f7 */
 
-       err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
        if (err && ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_ERR,
+               ata_dev_printk(dev, KERN_ERR,
                        "%s: ata_exec_internal failed: %u\n",
                        __FUNCTION__, err);
 }
 
 /**
  * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
- * @ap: the ata_port for the drive
- * @atadev: target ata_device
+ * @dev: target ATA device
  * @gtf_length: total number of bytes of _GTF taskfiles
  * @gtf_address: location of _GTF taskfile arrays
  *
@@ -517,30 +514,31 @@ static void taskfile_load_raw(struct ata_port *ap,
  * Write {gtf_address, length gtf_length} in groups of
  * REGS_PER_GTF bytes.
  */
-static int do_drive_set_taskfiles(struct ata_port *ap,
-               struct ata_device *atadev, unsigned int gtf_length,
-               unsigned long gtf_address)
+static int do_drive_set_taskfiles(struct ata_device *dev,
+                                 unsigned int gtf_length,
+                                 unsigned long gtf_address)
 {
-       int                     err = -ENODEV;
-       int                     gtf_count = gtf_length / REGS_PER_GTF;
-       int                     ix;
+       struct ata_port *ap = dev->ap;
+       int err = -ENODEV;
+       int gtf_count = gtf_length / REGS_PER_GTF;
+       int ix;
        struct taskfile_array   *gtf;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+               ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
                               __FUNCTION__, ap->port_no);
 
        if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
                return 0;
 
-       if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
+       if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
                goto out;
        if (!gtf_count)         /* shouldn't be here */
                goto out;
 
        if (gtf_length % REGS_PER_GTF) {
                if (ata_msg_drv(ap))
-                       ata_dev_printk(atadev, KERN_ERR,
+                       ata_dev_printk(dev, KERN_ERR,
                                "%s: unexpected GTF length (%d)\n",
                                __FUNCTION__, gtf_length);
                goto out;
@@ -551,7 +549,7 @@ static int do_drive_set_taskfiles(struct ata_port *ap,
                        (gtf_address + ix * REGS_PER_GTF);
 
                /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
-               taskfile_load_raw(ap, atadev, gtf);
+               taskfile_load_raw(dev, gtf);
        }
 
        err = 0;
@@ -567,11 +565,11 @@ out:
  */
 int ata_acpi_exec_tfs(struct ata_port *ap)
 {
-       int             ix;
-       int             ret =0;
-       unsigned int    gtf_length;
-       unsigned long   gtf_address;
-       unsigned long   obj_loc;
+       int ix;
+       int ret = 0;
+       unsigned int gtf_length;
+       unsigned long gtf_address;
+       unsigned long obj_loc;
 
        if (libata_noacpi)
                return 0;
@@ -584,11 +582,13 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
                return 0;
 
        for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
-               if (!ata_dev_enabled(&ap->device[ix]))
+               struct ata_device *dev = &ap->device[ix];
+
+               if (!ata_dev_enabled(dev))
                        continue;
 
-               ret = do_drive_get_GTF(ap, ix,
-                               &gtf_length, &gtf_address, &obj_loc);
+               ret = do_drive_get_GTF(dev, &gtf_length, &gtf_address,
+                                      &obj_loc);
                if (ret < 0) {
                        if (ata_msg_probe(ap))
                                ata_port_printk(ap, KERN_DEBUG,
@@ -597,8 +597,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
                        break;
                }
 
-               ret = do_drive_set_taskfiles(ap, &ap->device[ix],
-                               gtf_length, gtf_address);
+               ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address);
                kfree((void *)obj_loc);
                if (ret < 0) {
                        if (ata_msg_probe(ap))
@@ -614,8 +613,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
 
 /**
  * ata_acpi_push_id - send Identify data to drive
- * @ap: the ata_port for the drive
- * @ix: drive index
+ * @dev: target ATA device
  *
  * _SDD ACPI object: for SATA mode only
  * Must be after Identify (Packet) Device -- uses its data
@@ -623,57 +621,57 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
  * method and if it fails for whatever reason, we should still
  * just keep going.
  */
-int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+int ata_acpi_push_id(struct ata_device *dev)
 {
-       acpi_handle                     handle;
-       acpi_integer                    pcidevfn;
-       int                             err;
-       struct device                   *dev = ap->host->dev;
-       struct ata_device               *atadev = &ap->device[ix];
-       u32                             dev_adr;
-       acpi_status                     status;
-       struct acpi_object_list         input;
-       union acpi_object               in_params[1];
+       struct ata_port *ap = dev->ap;
+       acpi_handle handle;
+       acpi_integer pcidevfn;
+       int err;
+       struct device *gdev = ap->host->dev;
+       u32 dev_adr;
+       acpi_status status;
+       struct acpi_object_list input;
+       union acpi_object in_params[1];
 
        if (libata_noacpi)
                return 0;
 
        if (ata_msg_probe(ap))
-               ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
-                              __FUNCTION__, ix, ap->port_no);
+               ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
+                              __FUNCTION__, dev->devno, ap->port_no);
 
        /* Don't continue if not a SATA device. */
        if (!(ap->cbl == ATA_CBL_SATA)) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
+                       ata_dev_printk(dev, KERN_DEBUG,
                                "%s: Not a SATA device\n", __FUNCTION__);
                goto out;
        }
 
        /* Don't continue if device has no _ADR method.
         * _SDD is intended for known motherboard devices. */
-       err = sata_get_dev_handle(dev, &handle, &pcidevfn);
+       err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
        if (err < 0) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
+                       ata_dev_printk(dev, KERN_DEBUG,
                                "%s: sata_get_dev_handle failed (%d\n",
                                __FUNCTION__, err);
                goto out;
        }
 
        /* Get this drive's _ADR info, if not already known */
-       if (!atadev->obj_handle) {
+       if (!dev->obj_handle) {
                dev_adr = SATA_ADR_RSVD;
-               err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
+               err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
                                        &dev_adr);
                if (err < 0 || dev_adr == SATA_ADR_RSVD ||
-                       !atadev->obj_handle) {
+                       !dev->obj_handle) {
                        if (ata_msg_probe(ap))
-                               ata_dev_printk(atadev, KERN_DEBUG,
+                               ata_dev_printk(dev, KERN_DEBUG,
                                        "%s: get_sata_adr failed: "
                                        "err=%d, dev_adr=%u, obj_handle=0x%p\n",
                                        __FUNCTION__, err, dev_adr,
-                                       atadev->obj_handle);
+                                       dev->obj_handle);
                        goto out;
                }
        }
@@ -683,19 +681,19 @@ int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
        input.count = 1;
        input.pointer = in_params;
        in_params[0].type = ACPI_TYPE_BUFFER;
-       in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
-       in_params[0].buffer.pointer = (u8 *)atadev->id;
+       in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS;
+       in_params[0].buffer.pointer = (u8 *)dev->id;
        /* Output buffer: _SDD has no output */
 
        /* It's OK for _SDD to be missing too. */
-       swap_buf_le16(atadev->id, ATA_ID_WORDS);
-       status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
-       swap_buf_le16(atadev->id, ATA_ID_WORDS);
+       swap_buf_le16(dev->id, ATA_ID_WORDS);
+       status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL);
+       swap_buf_le16(dev->id, ATA_ID_WORDS);
 
        err = ACPI_FAILURE(status) ? -EIO : 0;
        if (err < 0) {
                if (ata_msg_probe(ap))
-                       ata_dev_printk(atadev, KERN_DEBUG,
+                       ata_dev_printk(dev, KERN_DEBUG,
                                       "%s _SDD error: status = 0x%x\n",
                                       __FUNCTION__, status);
        }
index 4595d1f8cf60e2a3875863c8e6f08297d08164d1..4166407eb47cf60496fccfa28a2a7b1d2a6bb411 100644 (file)
@@ -101,6 +101,12 @@ int libata_noacpi = 1;
 module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 
+int ata_spindown_compat = 1;
+module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
+                "behavior.  Will be removed.  More info can be found in "
+                "Documentation/feature-removal-schedule.txt\n");
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
@@ -1654,7 +1660,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
        const char *reason;
-       int tried_spinup = 0;
+       int may_fallback = 1, tried_spinup = 0;
        int rc;
 
        if (ata_msg_ctl(ap))
@@ -1698,11 +1704,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                        return -ENOENT;
                }
 
+               /* Device or controller might have reported the wrong
+                * device class.  Give a shot at the other IDENTIFY if
+                * the current one is aborted by the device.
+                */
+               if (may_fallback &&
+                   (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       may_fallback = 0;
+
+                       if (class == ATA_DEV_ATA)
+                               class = ATA_DEV_ATAPI;
+                       else
+                               class = ATA_DEV_ATA;
+                       goto retry;
+               }
+
                rc = -EIO;
                reason = "I/O error";
                goto err_out;
        }
 
+       /* Falling back doesn't make sense if ID data was read
+        * successfully at least once.
+        */
+       may_fallback = 0;
+
        swap_buf_le16(id, ATA_ID_WORDS);
 
        /* sanity check */
@@ -1843,7 +1869,7 @@ int ata_dev_configure(struct ata_device *dev)
                ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
        /* set _SDD */
-       rc = ata_acpi_push_id(ap, dev->devno);
+       rc = ata_acpi_push_id(dev);
        if (rc) {
                ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
                        rc);
@@ -2860,7 +2886,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
                dev = &ap->device[i];
 
                /* don't update suspended devices' xfer mode */
-               if (!ata_dev_ready(dev))
+               if (!ata_dev_enabled(dev))
                        continue;
 
                rc = ata_dev_set_mode(dev);
@@ -5845,37 +5871,11 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
  */
 int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
 {
-       int i, j, rc;
+       int rc;
 
        rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
-       if (rc)
-               goto fail;
-
-       /* EH is quiescent now.  Fail if we have any ready device.
-        * This happens if hotplug occurs between completion of device
-        * suspension and here.
-        */
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap = host->ports[i];
-
-               for (j = 0; j < ATA_MAX_DEVICES; j++) {
-                       struct ata_device *dev = &ap->device[j];
-
-                       if (ata_dev_ready(dev)) {
-                               ata_port_printk(ap, KERN_WARNING,
-                                               "suspend failed, device %d "
-                                               "still active\n", dev->devno);
-                               rc = -EBUSY;
-                               goto fail;
-                       }
-               }
-       }
-
-       host->dev->power.power_state = mesg;
-       return 0;
-
- fail:
-       ata_host_resume(host);
+       if (rc == 0)
+               host->dev->power.power_state = mesg;
        return rc;
 }
 
@@ -5984,6 +5984,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        if (!ap)
                return NULL;
 
+       ap->pflags |= ATA_PFLAG_INITIALIZING;
        ap->lock = &host->lock;
        ap->flags = ATA_FLAG_DISABLED;
        ap->print_id = -1;
@@ -6352,6 +6353,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                        ehi->action |= ATA_EH_SOFTRESET;
                        ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
+                       ap->pflags &= ~ATA_PFLAG_INITIALIZING;
                        ap->pflags |= ATA_PFLAG_LOADING;
                        ata_port_schedule_eh(ap);
 
@@ -6876,6 +6878,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
 EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6889,11 +6892,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter);
 EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
-EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
-#endif /* CONFIG_PM */
-
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
 EXPORT_SYMBOL_GPL(ata_port_abort);
index 8256655ce7d9ea3e50dd26fa4a00973b7958cf25..5309c312f5176e57e07138bb7f37e70daa56f148 100644 (file)
@@ -77,29 +77,12 @@ static void ata_eh_finish(struct ata_port *ap);
 #ifdef CONFIG_PM
 static void ata_eh_handle_port_suspend(struct ata_port *ap);
 static void ata_eh_handle_port_resume(struct ata_port *ap);
-static int ata_eh_suspend(struct ata_port *ap,
-                         struct ata_device **r_failed_dev);
-static void ata_eh_prep_resume(struct ata_port *ap);
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
 #else /* CONFIG_PM */
 static void ata_eh_handle_port_suspend(struct ata_port *ap)
 { }
 
 static void ata_eh_handle_port_resume(struct ata_port *ap)
 { }
-
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-       return 0;
-}
-
-static void ata_eh_prep_resume(struct ata_port *ap)
-{ }
-
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-       return 0;
-}
 #endif /* CONFIG_PM */
 
 static void ata_ering_record(struct ata_ering *ering, int is_io,
@@ -568,6 +551,9 @@ void ata_port_schedule_eh(struct ata_port *ap)
 {
        WARN_ON(!ap->ops->error_handler);
 
+       if (ap->pflags & ATA_PFLAG_INITIALIZING)
+               return;
+
        ap->pflags |= ATA_PFLAG_EH_PENDING;
        scsi_schedule_eh(ap->scsi_host);
 
@@ -1791,7 +1777,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
                if (ehc->i.flags & ATA_EHI_DID_RESET)
                        readid_flags |= ATA_READID_POSTRESET;
 
-               if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
+               if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
                        if (ata_port_offline(ap)) {
                                rc = -EIO;
                                goto err;
@@ -1872,166 +1858,6 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
        return rc;
 }
 
-#ifdef CONFIG_PM
-/**
- *     ata_eh_suspend - handle suspend EH action
- *     @ap: target host port
- *     @r_failed_dev: result parameter to indicate failing device
- *
- *     Handle suspend EH action.  Disk devices are spinned down and
- *     other types of devices are just marked suspended.  Once
- *     suspended, no EH action to the device is allowed until it is
- *     resumed.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise
- */
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-       struct ata_device *dev;
-       int i, rc = 0;
-
-       DPRINTK("ENTER\n");
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               unsigned long flags;
-               unsigned int action, err_mask;
-
-               dev = &ap->device[i];
-               action = ata_eh_dev_action(dev);
-
-               if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
-                       continue;
-
-               WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
-
-               ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
-
-               if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
-                       /* flush cache */
-                       rc = ata_flush_cache(dev);
-                       if (rc)
-                               break;
-
-                       /* spin down */
-                       err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
-                       if (err_mask) {
-                               ata_dev_printk(dev, KERN_ERR, "failed to "
-                                              "spin down (err_mask=0x%x)\n",
-                                              err_mask);
-                               rc = -EIO;
-                               break;
-                       }
-               }
-
-               spin_lock_irqsave(ap->lock, flags);
-               dev->flags |= ATA_DFLAG_SUSPENDED;
-               spin_unlock_irqrestore(ap->lock, flags);
-
-               ata_eh_done(ap, dev, ATA_EH_SUSPEND);
-       }
-
-       if (rc)
-               *r_failed_dev = dev;
-
-       DPRINTK("EXIT\n");
-       return rc;
-}
-
-/**
- *     ata_eh_prep_resume - prep for resume EH action
- *     @ap: target host port
- *
- *     Clear SUSPENDED in preparation for scheduled resume actions.
- *     This allows other parts of EH to access the devices being
- *     resumed.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- */
-static void ata_eh_prep_resume(struct ata_port *ap)
-{
-       struct ata_device *dev;
-       unsigned long flags;
-       int i;
-
-       DPRINTK("ENTER\n");
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               unsigned int action;
-
-               dev = &ap->device[i];
-               action = ata_eh_dev_action(dev);
-
-               if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
-                       continue;
-
-               spin_lock_irqsave(ap->lock, flags);
-               dev->flags &= ~ATA_DFLAG_SUSPENDED;
-               spin_unlock_irqrestore(ap->lock, flags);
-       }
-
-       DPRINTK("EXIT\n");
-}
-
-/**
- *     ata_eh_resume - handle resume EH action
- *     @ap: target host port
- *     @r_failed_dev: result parameter to indicate failing device
- *
- *     Handle resume EH action.  Target devices are already reset and
- *     revalidated.  Spinning up is the only operation left.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise
- */
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-       struct ata_device *dev;
-       int i, rc = 0;
-
-       DPRINTK("ENTER\n");
-
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               unsigned int action, err_mask;
-
-               dev = &ap->device[i];
-               action = ata_eh_dev_action(dev);
-
-               if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
-                       continue;
-
-               ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
-
-               if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
-                       err_mask = ata_do_simple_cmd(dev,
-                                                    ATA_CMD_IDLEIMMEDIATE);
-                       if (err_mask) {
-                               ata_dev_printk(dev, KERN_ERR, "failed to "
-                                              "spin up (err_mask=0x%x)\n",
-                                              err_mask);
-                               rc = -EIO;
-                               break;
-                       }
-               }
-
-               ata_eh_done(ap, dev, ATA_EH_RESUME);
-       }
-
-       if (rc)
-               *r_failed_dev = dev;
-
-       DPRINTK("EXIT\n");
-       return 0;
-}
-#endif /* CONFIG_PM */
-
 static int ata_port_nr_enabled(struct ata_port *ap)
 {
        int i, cnt = 0;
@@ -2057,17 +1883,6 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
        struct ata_eh_context *ehc = &ap->eh_context;
        int i;
 
-       /* skip if all possible devices are suspended */
-       for (i = 0; i < ata_port_max_devices(ap); i++) {
-               struct ata_device *dev = &ap->device[i];
-
-               if (!(dev->flags & ATA_DFLAG_SUSPENDED))
-                       break;
-       }
-
-       if (i == ata_port_max_devices(ap))
-               return 1;
-
        /* thaw frozen port, resume link and recover failed devices */
        if ((ap->pflags & ATA_PFLAG_FROZEN) ||
            (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
@@ -2147,9 +1962,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
        if (ap->pflags & ATA_PFLAG_UNLOADING)
                goto out;
 
-       /* prep for resume */
-       ata_eh_prep_resume(ap);
-
        /* skip EH if possible. */
        if (ata_eh_skip_recovery(ap))
                ehc->i.action = 0;
@@ -2177,11 +1989,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
        if (rc)
                goto dev_fail;
 
-       /* resume devices */
-       rc = ata_eh_resume(ap, &dev);
-       if (rc)
-               goto dev_fail;
-
        /* configure transfer mode if necessary */
        if (ehc->i.flags & ATA_EHI_SETMODE) {
                rc = ata_set_mode(ap, &dev);
@@ -2190,25 +1997,16 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                ehc->i.flags &= ~ATA_EHI_SETMODE;
        }
 
-       /* suspend devices */
-       rc = ata_eh_suspend(ap, &dev);
-       if (rc)
-               goto dev_fail;
-
        goto out;
 
  dev_fail:
        ehc->tries[dev->devno]--;
 
        switch (rc) {
-       case -EINVAL:
-               /* eeek, something went very wrong, give up */
-               ehc->tries[dev->devno] = 0;
-               break;
-
        case -ENODEV:
                /* device missing or wrong IDENTIFY data, schedule probing */
                ehc->i.probe_mask |= (1 << dev->devno);
+       case -EINVAL:
                /* give it just one more chance */
                ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
        case -EIO:
@@ -2390,22 +2188,13 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
  *
  *     Resume @ap.
  *
- *     This function also waits upto one second until all devices
- *     hanging off this port requests resume EH action.  This is to
- *     prevent invoking EH and thus reset multiple times on resume.
- *
- *     On DPM resume, where some of devices might not be resumed
- *     together, this may delay port resume upto one second, but such
- *     DPM resumes are rare and 1 sec delay isn't too bad.
- *
  *     LOCKING:
  *     Kernel thread context (may sleep).
  */
 static void ata_eh_handle_port_resume(struct ata_port *ap)
 {
-       unsigned long timeout;
        unsigned long flags;
-       int i, rc = 0;
+       int rc = 0;
 
        /* are we resuming? */
        spin_lock_irqsave(ap->lock, flags);
@@ -2416,31 +2205,12 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
        }
        spin_unlock_irqrestore(ap->lock, flags);
 
-       /* spurious? */
-       if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
-               goto done;
+       WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
 
        if (ap->ops->port_resume)
                rc = ap->ops->port_resume(ap);
 
-       /* give devices time to request EH */
-       timeout = jiffies + HZ; /* 1s max */
-       while (1) {
-               for (i = 0; i < ATA_MAX_DEVICES; i++) {
-                       struct ata_device *dev = &ap->device[i];
-                       unsigned int action = ata_eh_dev_action(dev);
-
-                       if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
-                           !(action & ATA_EH_RESUME))
-                               break;
-               }
-
-               if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
-                       break;
-               msleep(10);
-       }
-
- done:
+       /* report result */
        spin_lock_irqsave(ap->lock, flags);
        ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
        if (ap->pm_result) {
index 9afba2ba489e52097bc5fca2fe8fd98747b6b887..dd81fa78cdcf62039c92993b96843c982ec06ee5 100644 (file)
@@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
        }
 }
 
-#ifdef CONFIG_PM
-/**
- *     ata_scsi_device_suspend - suspend ATA device associated with sdev
- *     @sdev: the SCSI device to suspend
- *     @mesg: target power management message
- *
- *     Request suspend EH action on the ATA device associated with
- *     @sdev and wait for the operation to complete.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0 on success, -errno otherwise.
- */
-int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg)
-{
-       struct ata_port *ap = ata_shost_to_port(sdev->host);
-       struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
-       unsigned long flags;
-       unsigned int action;
-       int rc = 0;
-
-       if (!dev)
-               goto out;
-
-       spin_lock_irqsave(ap->lock, flags);
-
-       /* wait for the previous resume to complete */
-       while (dev->flags & ATA_DFLAG_SUSPENDED) {
-               spin_unlock_irqrestore(ap->lock, flags);
-               ata_port_wait_eh(ap);
-               spin_lock_irqsave(ap->lock, flags);
-       }
-
-       /* if @sdev is already detached, nothing to do */
-       if (sdev->sdev_state == SDEV_OFFLINE ||
-           sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
-               goto out_unlock;
-
-       /* request suspend */
-       action = ATA_EH_SUSPEND;
-       if (mesg.event != PM_EVENT_SUSPEND)
-               action |= ATA_EH_PM_FREEZE;
-       ap->eh_info.dev_action[dev->devno] |= action;
-       ap->eh_info.flags |= ATA_EHI_QUIET;
-       ata_port_schedule_eh(ap);
-
-       spin_unlock_irqrestore(ap->lock, flags);
-
-       /* wait for EH to do the job */
-       ata_port_wait_eh(ap);
-
-       spin_lock_irqsave(ap->lock, flags);
-
-       /* If @sdev is still attached but the associated ATA device
-        * isn't suspended, the operation failed.
-        */
-       if (sdev->sdev_state != SDEV_OFFLINE &&
-           sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL &&
-           !(dev->flags & ATA_DFLAG_SUSPENDED))
-               rc = -EIO;
-
- out_unlock:
-       spin_unlock_irqrestore(ap->lock, flags);
- out:
-       if (rc == 0)
-               sdev->sdev_gendev.power.power_state = mesg;
-       return rc;
-}
-
-/**
- *     ata_scsi_device_resume - resume ATA device associated with sdev
- *     @sdev: the SCSI device to resume
- *
- *     Request resume EH action on the ATA device associated with
- *     @sdev and return immediately.  This enables parallel
- *     wakeup/spinup of devices.
- *
- *     LOCKING:
- *     Kernel thread context (may sleep).
- *
- *     RETURNS:
- *     0.
- */
-int ata_scsi_device_resume(struct scsi_device *sdev)
-{
-       struct ata_port *ap = ata_shost_to_port(sdev->host);
-       struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
-       struct ata_eh_info *ehi = &ap->eh_info;
-       unsigned long flags;
-       unsigned int action;
-
-       if (!dev)
-               goto out;
-
-       spin_lock_irqsave(ap->lock, flags);
-
-       /* if @sdev is already detached, nothing to do */
-       if (sdev->sdev_state == SDEV_OFFLINE ||
-           sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
-               goto out_unlock;
-
-       /* request resume */
-       action = ATA_EH_RESUME;
-       if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND)
-               __ata_ehi_hotplugged(ehi);
-       else
-               action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET;
-       ehi->dev_action[dev->devno] |= action;
-
-       /* We don't want autopsy and verbose EH messages.  Disable
-        * those if we're the only device on this link.
-        */
-       if (ata_port_max_devices(ap) == 1)
-               ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
-       ata_port_schedule_eh(ap);
-
- out_unlock:
-       spin_unlock_irqrestore(ap->lock, flags);
- out:
-       sdev->sdev_gendev.power.power_state = PMSG_ON;
-       return 0;
-}
-#endif /* CONFIG_PM */
-
 /**
  *     ata_to_sense_error - convert ATA error to SCSI error
  *     @id: ATA device number
@@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
 
        blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
 
+       sdev->manage_start_stop = 1;
+
        if (dev)
                ata_scsi_dev_config(sdev, dev);
 
@@ -1069,9 +944,35 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
                }
 
                tf->command = ATA_CMD_VERIFY;   /* READ VERIFY */
-       } else
+       } else {
+               /* XXX: This is for backward compatibility, will be
+                * removed.  Read Documentation/feature-removal-schedule.txt
+                * for more info.
+                */
+               if (ata_spindown_compat &&
+                   (system_state == SYSTEM_HALT ||
+                    system_state == SYSTEM_POWER_OFF)) {
+                       static int warned = 0;
+
+                       if (!warned) {
+                               spin_unlock_irq(qc->ap->lock);
+                               ata_dev_printk(qc->dev, KERN_WARNING,
+                                       "DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
+                                       "UPDATE SHUTDOWN UTILITY\n");
+                               ata_dev_printk(qc->dev, KERN_WARNING,
+                                       "For more info, visit "
+                                       "http://linux-ata.org/shutdown.html\n");
+                               warned = 1;
+                               ssleep(5);
+                               spin_lock_irq(qc->ap->lock);
+                       }
+                       scmd->result = SAM_STAT_GOOD;
+                       return 1;
+               }
+
                /* Issue ATA STANDBY IMMEDIATE command */
                tf->command = ATA_CMD_STANDBYNOW1;
+       }
 
        /*
         * Standby and Idle condition timers could be implemented but that
index d211db6b35a2588bbf4521b884ec2329795ccd69..e35d13466c69092c68e822f4cb150b6f492cefab 100644 (file)
@@ -544,7 +544,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-static int ata_pci_init_bmdma(struct ata_host *host)
+int ata_pci_init_bmdma(struct ata_host *host)
 {
        struct device *gdev = host->dev;
        struct pci_dev *pdev = to_pci_dev(gdev);
@@ -566,7 +566,7 @@ static int ata_pci_init_bmdma(struct ata_host *host)
        }
        host->iomap = pcim_iomap_table(pdev);
 
-       for (i = 0; i < host->n_ports; i++) {
+       for (i = 0; i < 2; i++) {
                struct ata_port *ap = host->ports[i];
                void __iomem *bmdma = host->iomap[4] + 8 * i;
 
@@ -585,54 +585,52 @@ static int ata_pci_init_bmdma(struct ata_host *host)
 /**
  *     ata_pci_init_native_host - acquire native ATA resources and init host
  *     @host: target ATA host
- *     @port_mask: ports to consider
  *
- *     Acquire native PCI ATA resources for @host and initialize
- *     @host accordoingly.
+ *     Acquire native PCI ATA resources for @host and initialize the
+ *     first two ports of @host accordingly.  Ports marked dummy are
+ *     skipped and allocation failure makes the port dummy.
  *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
  *
  *     RETURNS:
- *     0 on success, -errno otherwise.
+ *     0 if at least one port is initialized, -ENODEV if no port is
+ *     available.
  */
-int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
+int ata_pci_init_native_host(struct ata_host *host)
 {
        struct device *gdev = host->dev;
        struct pci_dev *pdev = to_pci_dev(gdev);
+       unsigned int mask = 0;
        int i, rc;
 
-       /* Discard disabled ports.  Some controllers show their unused
-        * channels this way.  Disabled ports are made dummy.
-        */
-       for (i = 0; i < 2; i++) {
-               if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
-                       host->ports[i]->ops = &ata_dummy_port_ops;
-                       port_mask &= ~(1 << i);
-               }
-       }
-
-       if (!port_mask) {
-               dev_printk(KERN_ERR, gdev, "no available port\n");
-               return -ENODEV;
-       }
-
        /* request, iomap BARs and init port addresses accordingly */
        for (i = 0; i < 2; i++) {
                struct ata_port *ap = host->ports[i];
                int base = i * 2;
                void __iomem * const *iomap;
 
-               if (!(port_mask & (1 << i)))
+               if (ata_port_is_dummy(ap))
+                       continue;
+
+               /* Discard disabled ports.  Some controllers show
+                * their unused channels this way.  Disabled ports are
+                * made dummy.
+                */
+               if (!ata_resources_present(pdev, i)) {
+                       ap->ops = &ata_dummy_port_ops;
                        continue;
+               }
 
                rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
                if (rc) {
-                       dev_printk(KERN_ERR, gdev, "failed to request/iomap "
-                                  "BARs for port %d (errno=%d)\n", i, rc);
+                       dev_printk(KERN_WARNING, gdev,
+                                  "failed to request/iomap BARs for port %d "
+                                  "(errno=%d)\n", i, rc);
                        if (rc == -EBUSY)
                                pcim_pin_device(pdev);
-                       return rc;
+                       ap->ops = &ata_dummy_port_ops;
+                       continue;
                }
                host->iomap = iomap = pcim_iomap_table(pdev);
 
@@ -641,6 +639,13 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
                ap->ioaddr.ctl_addr = (void __iomem *)
                        ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
                ata_std_ports(&ap->ioaddr);
+
+               mask |= 1 << i;
+       }
+
+       if (!mask) {
+               dev_printk(KERN_ERR, gdev, "no available native port\n");
+               return -ENODEV;
        }
 
        return 0;
@@ -649,8 +654,7 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
 /**
  *     ata_pci_prepare_native_host - helper to prepare native PCI ATA host
  *     @pdev: target PCI device
- *     @ppi: array of port_info
- *     @n_ports: number of ports to allocate
+ *     @ppi: array of port_info, must be enough for two ports
  *     @r_host: out argument for the initialized ATA host
  *
  *     Helper to allocate ATA host for @pdev, acquire all native PCI
@@ -664,10 +668,9 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
  */
 int ata_pci_prepare_native_host(struct pci_dev *pdev,
                                const struct ata_port_info * const * ppi,
-                               int n_ports, struct ata_host **r_host)
+                               struct ata_host **r_host)
 {
        struct ata_host *host;
-       unsigned int port_mask;
        int rc;
 
        if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
@@ -681,11 +684,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
                goto err_out;
        }
 
-       port_mask = ATA_PORT_PRIMARY;
-       if (n_ports > 1)
-               port_mask |= ATA_PORT_SECONDARY;
-
-       rc = ata_pci_init_native_host(host, port_mask);
+       rc = ata_pci_init_native_host(host);
        if (rc)
                goto err_out;
 
@@ -777,8 +776,11 @@ static int ata_init_legacy_port(struct ata_port *ap,
        /* iomap cmd and ctl ports */
        legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
        legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
-       if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
+       if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
+               dev_printk(KERN_WARNING, host->dev,
+                          "failed to map cmd/ctl ports\n");
                return -ENOMEM;
+       }
 
        /* init IO addresses */
        ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
@@ -792,19 +794,20 @@ static int ata_init_legacy_port(struct ata_port *ap,
 /**
  *     ata_init_legacy_host - acquire legacy ATA resources and init ATA host
  *     @host: target ATA host
- *     @legacy_mask: out parameter, mask indicating ports is in legacy mode
  *     @was_busy: out parameter, indicates whether any port was busy
  *
- *     Acquire legacy ATA resources for ports.
+ *     Acquire legacy ATA resources for the first two ports of @host
+ *     and initialize it accordingly.  Ports marked dummy are skipped
+ *     and resource acquistion failure makes the port dummy.
  *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
  *
  *     RETURNS:
- *     0 on success, -errno otherwise.
+ *     0 if at least one port is initialized, -ENODEV if no port is
+ *     available.
  */
-static int ata_init_legacy_host(struct ata_host *host,
-                               unsigned int *legacy_mask, int *was_busy)
+static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
 {
        struct device *gdev = host->dev;
        struct ata_legacy_devres *legacy_dr;
@@ -821,22 +824,23 @@ static int ata_init_legacy_host(struct ata_host *host,
        devres_add(gdev, legacy_dr);
 
        for (i = 0; i < 2; i++) {
-               *legacy_mask &= ~(1 << i);
+               if (ata_port_is_dummy(host->ports[i]))
+                       continue;
+
                rc = ata_init_legacy_port(host->ports[i], legacy_dr);
                if (rc == 0)
                        legacy_dr->mask |= 1 << i;
-               else if (rc == -EBUSY)
-                       (*was_busy)++;
-       }
-
-       if (!legacy_dr->mask)
-               return -EBUSY;
-
-       for (i = 0; i < 2; i++)
-               if (!(legacy_dr->mask & (1 << i)))
+               else {
+                       if (rc == -EBUSY)
+                               (*was_busy)++;
                        host->ports[i]->ops = &ata_dummy_port_ops;
+               }
+       }
 
-       *legacy_mask |= legacy_dr->mask;
+       if (!legacy_dr->mask) {
+               dev_printk(KERN_ERR, gdev, "no available legacy port\n");
+               return -ENODEV;
+       }
 
        devres_remove_group(gdev, NULL);
        return 0;
@@ -875,7 +879,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
        legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
        BUG_ON(!legacy_dr);
 
-       for (i = 0; i < host->n_ports; i++) {
+       for (i = 0; i < 2; i++) {
                unsigned int irq;
 
                /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
@@ -923,8 +927,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
 /**
  *     ata_pci_init_one - Initialize/register PCI IDE host controller
  *     @pdev: Controller to be initialized
- *     @port_info: Information from low-level host driver
- *     @n_ports: Number of ports attached to host controller
+ *     @ppi: array of port_info, must be enough for two ports
  *
  *     This is a helper function which can be called from a driver's
  *     xxx_init_one() probe function if the hardware uses traditional
@@ -944,26 +947,34 @@ static int ata_request_legacy_irqs(struct ata_host *host,
  *     RETURNS:
  *     Zero on success, negative on errno-based value on error.
  */
-
-int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
-                     unsigned int n_ports)
+int ata_pci_init_one(struct pci_dev *pdev,
+                    const struct ata_port_info * const * ppi)
 {
        struct device *dev = &pdev->dev;
+       const struct ata_port_info *pi = NULL;
        struct ata_host *host = NULL;
-       const struct ata_port_info *port[2];
        u8 mask;
-       unsigned int legacy_mode = 0;
-       int rc;
+       int legacy_mode = 0;
+       int i, rc;
 
        DPRINTK("ENTER\n");
 
-       if (!devres_open_group(dev, NULL, GFP_KERNEL))
-               return -ENOMEM;
+       /* look up the first valid port_info */
+       for (i = 0; i < 2 && ppi[i]; i++) {
+               if (ppi[i]->port_ops != &ata_dummy_port_ops) {
+                       pi = ppi[i];
+                       break;
+               }
+       }
 
-       BUG_ON(n_ports < 1 || n_ports > 2);
+       if (!pi) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "no valid port_info specified\n");
+               return -EINVAL;
+       }
 
-       port[0] = port_info[0];
-       port[1] = (n_ports > 1) ? port_info[1] : NULL;
+       if (!devres_open_group(dev, NULL, GFP_KERNEL))
+               return -ENOMEM;
 
        /* FIXME: Really for ATA it isn't safe because the device may be
           multi-purpose and we want to leave it alone if it was already
@@ -984,7 +995,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
                mask = (1 << 2) | (1 << 0);
                if ((tmp8 & mask) != mask)
-                       legacy_mode = (1 << 3);
+                       legacy_mode = 1;
 #if defined(CONFIG_NO_ATA_LEGACY)
                /* Some platforms with PCI limits cannot address compat
                   port space. In that case we punt if their firmware has
@@ -998,7 +1009,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
        }
 
        /* alloc and init host */
-       host = ata_host_alloc_pinfo(dev, port, n_ports);
+       host = ata_host_alloc_pinfo(dev, ppi, 2);
        if (!host) {
                dev_printk(KERN_ERR, &pdev->dev,
                           "failed to allocate ATA host\n");
@@ -1007,19 +1018,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
        }
 
        if (!legacy_mode) {
-               unsigned int port_mask;
-
-               port_mask = ATA_PORT_PRIMARY;
-               if (n_ports > 1)
-                       port_mask |= ATA_PORT_SECONDARY;
-
-               rc = ata_pci_init_native_host(host, port_mask);
+               rc = ata_pci_init_native_host(host);
                if (rc)
                        goto err_out;
        } else {
                int was_busy = 0;
 
-               rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
+               rc = ata_init_legacy_host(host, &was_busy);
                if (was_busy)
                        pcim_pin_device(pdev);
                if (rc)
@@ -1040,8 +1045,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out;
 
        if (!legacy_mode)
-               rc = devm_request_irq(dev, pdev->irq,
-                                     port_info[0]->port_ops->irq_handler,
+               rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
                                      IRQF_SHARED, DRV_NAME, host);
        else {
                irq_handler_t handler[2] = { host->ops->irq_handler,
@@ -1055,7 +1059,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out;
 
        /* register */
-       rc = ata_host_register(host, port_info[0]->sht);
+       rc = ata_host_register(host, pi->sht);
        if (rc)
                goto err_out;
 
index 5f4d40cd32888a9aaae5c3dc76a2bb3d84bd69aa..8b71b73a199cfa49e62eb4f0467f817836746e70 100644 (file)
@@ -58,6 +58,7 @@ extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
 extern int libata_noacpi;
+extern int ata_spindown_compat;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
                           u64 block, u32 n_block, unsigned int tf_flags,
@@ -96,15 +97,15 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern struct ata_port *ata_port_alloc(struct ata_host *host);
 
 /* libata-acpi.c */
-#ifdef CONFIG_SATA_ACPI
+#ifdef CONFIG_ATA_ACPI
 extern int ata_acpi_exec_tfs(struct ata_port *ap);
-extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
+extern int ata_acpi_push_id(struct ata_device *dev);
 #else
 static inline int ata_acpi_exec_tfs(struct ata_port *ap)
 {
        return 0;
 }
-static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+static inline int ata_acpi_push_id(struct ata_device *dev)
 {
        return 0;
 }
index d40edebb510a59ba41b6fbbd1600a8d9530a19a8..3c55a5ff74c761ac8cf9e00d5056146458cae1ee 100644 (file)
@@ -291,10 +291,6 @@ static struct scsi_host_template ali_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 /*
@@ -522,14 +518,14 @@ static void ali_init_chipset(struct pci_dev *pdev)
 
 static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info_early = {
+       static const struct ata_port_info info_early = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &ali_early_port_ops
        };
        /* Revision 0x20 added DMA */
-       static struct ata_port_info info_20 = {
+       static const struct ata_port_info info_20 = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
@@ -537,7 +533,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_20_port_ops
        };
        /* Revision 0x20 with support logic added UDMA */
-       static struct ata_port_info info_20_udma = {
+       static const struct ata_port_info info_20_udma = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
@@ -546,7 +542,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_20_port_ops
        };
        /* Revision 0xC2 adds UDMA66 */
-       static struct ata_port_info info_c2 = {
+       static const struct ata_port_info info_c2 = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
@@ -555,7 +551,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC3 is UDMA100 */
-       static struct ata_port_info info_c3 = {
+       static const struct ata_port_info info_c3 = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
@@ -564,7 +560,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC4 is UDMA133 */
-       static struct ata_port_info info_c4 = {
+       static const struct ata_port_info info_c4 = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
                .pio_mask = 0x1f,
@@ -573,7 +569,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_c2_port_ops
        };
        /* Revision 0xC5 is UDMA133 with LBA48 DMA */
-       static struct ata_port_info info_c5 = {
+       static const struct ata_port_info info_c5 = {
                .sht = &ali_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -582,7 +578,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &ali_c5_port_ops
        };
 
-       static struct ata_port_info *port_info[2];
+       const struct ata_port_info *ppi[] = { NULL, NULL };
        u8 rev, tmp;
        struct pci_dev *isa_bridge;
 
@@ -594,17 +590,17 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
         */
 
        if (rev < 0x20) {
-               port_info[0] = port_info[1] = &info_early;
+               ppi[0] = &info_early;
        } else if (rev < 0xC2) {
-               port_info[0] = port_info[1] = &info_20;
+               ppi[0] = &info_20;
        } else if (rev == 0xC2) {
-               port_info[0] = port_info[1] = &info_c2;
+               ppi[0] = &info_c2;
        } else if (rev == 0xC3) {
-               port_info[0] = port_info[1] = &info_c3;
+               ppi[0] = &info_c3;
        } else if (rev == 0xC4) {
-               port_info[0] = port_info[1] = &info_c4;
+               ppi[0] = &info_c4;
        } else
-               port_info[0] = port_info[1] = &info_c5;
+               ppi[0] = &info_c5;
 
        ali_init_chipset(pdev);
 
@@ -613,10 +609,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                /* Are we paired with a UDMA capable chip */
                pci_read_config_byte(isa_bridge, 0x5E, &tmp);
                if ((tmp & 0x1E) == 0x12)
-                       port_info[0] = port_info[1] = &info_20_udma;
+                       ppi[0] = &info_20_udma;
                pci_dev_put(isa_bridge);
        }
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index 67c7e87dec042417bf33e426091216570012d075..b439351f1fd3bc215994e36ce88d64a20f933864 100644 (file)
@@ -324,10 +324,6 @@ static struct scsi_host_template amd_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations amd33_port_ops = {
@@ -542,7 +538,7 @@ static struct ata_port_operations nv133_port_ops = {
 
 static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info[10] = {
+       static const struct ata_port_info info[10] = {
                {       /* 0: AMD 7401 */
                        .sht = &amd_sht,
                        .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -624,7 +620,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        .port_ops = &amd100_port_ops
                }
        };
-       static struct ata_port_info *port_info[2];
+       const struct ata_port_info *ppi[] = { NULL, NULL };
        static int printed_version;
        int type = id->driver_data;
        u8 rev;
@@ -656,9 +652,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ata_pci_clear_simplex(pdev);
 
        /* And fire it up */
-
-       port_info[0] = port_info[1] = &info[type];
-       return ata_pci_init_one(pdev, port_info, 2);
+       ppi[0] = &info[type];
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index ef51940c3adb36e7f2a8c4f9d80aec185ddc8567..9861059dd67370f073a1e5621cc3a3b47172a015 100644 (file)
@@ -414,7 +414,7 @@ static const struct ata_port_operations artop6260_ops = {
 static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
 {
        static int printed_version;
-       static struct ata_port_info info_6210 = {
+       static const struct ata_port_info info_6210 = {
                .sht            = &artop_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -422,7 +422,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask      = ATA_UDMA2,
                .port_ops       = &artop6210_ops,
        };
-       static struct ata_port_info info_626x = {
+       static const struct ata_port_info info_626x = {
                .sht            = &artop_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -430,7 +430,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask      = ATA_UDMA4,
                .port_ops       = &artop6260_ops,
        };
-       static struct ata_port_info info_626x_fast = {
+       static const struct ata_port_info info_626x_fast = {
                .sht            = &artop_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -438,32 +438,30 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask      = ATA_UDMA5,
                .port_ops       = &artop6260_ops,
        };
-       struct ata_port_info *port_info[2];
-       struct ata_port_info *info = NULL;
-       int ports = 2;
+       const struct ata_port_info *ppi[] = { NULL, NULL };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
        if (id->driver_data == 0) {     /* 6210 variant */
-               info = &info_6210;
+               ppi[0] = &info_6210;
+               ppi[1] = &ata_dummy_port_info;
                /* BIOS may have left us in UDMA, clear it before libata probe */
                pci_write_config_byte(pdev, 0x54, 0);
                /* For the moment (also lacks dsc) */
                printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
                printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
-               ports = 1;
        }
        else if (id->driver_data == 1)  /* 6260 */
-               info = &info_626x;
+               ppi[0] = &info_626x;
        else if (id->driver_data == 2)  { /* 6260 or 6260 + fast */
                unsigned long io = pci_resource_start(pdev, 4);
                u8 reg;
 
-               info = &info_626x;
+               ppi[0] = &info_626x;
                if (inb(io) & 0x10)
-                       info = &info_626x_fast;
+                       ppi[0] = &info_626x_fast;
                /* Mac systems come up with some registers not set as we
                   will need them */
 
@@ -484,10 +482,9 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
 
        }
 
-       BUG_ON(info == NULL);
+       BUG_ON(ppi[0] == NULL);
 
-       port_info[0] = port_info[1] = info;
-       return ata_pci_init_one(pdev, port_info, ports);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id artop_pci_tbl[] = {
index 21515381b5b34759479053b9c0d51edcb106ddca..844914681a2ab545f05eb468aafcda747f900b2a 100644 (file)
@@ -229,10 +229,6 @@ static struct scsi_host_template atiixp_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations atiixp_port_ops = {
@@ -272,7 +268,7 @@ static struct ata_port_operations atiixp_port_ops = {
 
 static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &atiixp_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -280,8 +276,8 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x3F,
                .port_ops = &atiixp_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
-       return ata_pci_init_one(dev, port_info, 2);
+       const struct ata_port_info *ppi[] = { &info, NULL };
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id atiixp[] = {
index 2105985a80135faadbb8b1df84083408a9068ebe..ed00fa9d53be6191145db25f243962b6d8fd9ec7 100644 (file)
@@ -181,10 +181,6 @@ static struct scsi_host_template cmd640_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cmd640_port_ops = {
@@ -253,17 +249,16 @@ static void cmd640_hardware_init(struct pci_dev *pdev)
 
 static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &cmd640_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &cmd640_port_ops
        };
-
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        cmd640_hardware_init(pdev);
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static int cmd640_reinit_one(struct pci_dev *pdev)
index 3989cc577fcd503b6e073a001f89eb72d935b6f0..2a79b335cfcc43d939529716ca46c38f4437106b 100644 (file)
@@ -266,10 +266,6 @@ static struct scsi_host_template cmd64x_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cmd64x_port_ops = {
@@ -381,7 +377,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        u32 class_rev;
 
-       static struct ata_port_info cmd_info[6] = {
+       static const struct ata_port_info cmd_info[6] = {
                {       /* CMD 643 - no UDMA */
                        .sht = &cmd64x_sht,
                        .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -428,11 +424,9 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        .port_ops = &cmd648_port_ops
                }
        };
-       static struct ata_port_info *port_info[2], *info;
+       const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
        u8 mrdmode;
 
-       info = &cmd_info[id->driver_data];
-
        pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xFF;
 
@@ -442,10 +436,10 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (pdev->device == PCI_DEVICE_ID_CMD_646) {
                /* Does UDMA work ? */
                if (class_rev > 4)
-                       info = &cmd_info[2];
+                       ppi[0] = &cmd_info[2];
                /* Early rev with other problems ? */
                else if (class_rev == 1)
-                       info = &cmd_info[3];
+                       ppi[0] = &cmd_info[3];
        }
 
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
@@ -461,8 +455,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
 
-       port_info[0] = port_info[1] = info;
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index 79bef0d1fad337106eb77d419bf192090834fc80..83bcc5b32597e733ef14017625f90659cba8f15f 100644 (file)
@@ -155,10 +155,6 @@ static struct scsi_host_template cs5520_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5520_port_ops = {
index 29642d5ee1891ee3d3aef8e40d51008f986b2fbc..1b67923d7a4ead8add4ac282290447716d0ffabe 100644 (file)
@@ -176,10 +176,6 @@ static struct scsi_host_template cs5530_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5530_port_ops = {
@@ -339,7 +335,7 @@ fail_put:
 
 static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &cs5530_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -348,23 +344,23 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &cs5530_port_ops
        };
        /* The docking connector doesn't do UDMA, and it seems not MWDMA */
-       static struct ata_port_info info_palmax_secondary = {
+       static const struct ata_port_info info_palmax_secondary = {
                .sht = &cs5530_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &cs5530_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        /* Chip initialisation */
        if (cs5530_init_chip())
                return -ENODEV;
 
        if (cs5530_is_palmax())
-               port_info[1] = &info_palmax_secondary;
+               ppi[1] = &info_palmax_secondary;
 
        /* Now kick off ATA set up */
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index 22006ae719411a52218bcfb96a161d702fdce39e..f37d4cd812a17510ce46fc142e1a79037a248883 100644 (file)
@@ -173,10 +173,6 @@ static struct scsi_host_template cs5535_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5535_port_ops = {
@@ -227,7 +223,7 @@ static struct ata_port_operations cs5535_port_ops = {
 
 static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &cs5535_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -235,7 +231,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x1f,
                .port_ops = &cs5535_port_ops
        };
-       struct ata_port_info *ports[1] = { &info };
+       const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
 
        u32 timings, dummy;
 
@@ -247,7 +243,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        rdmsr(ATAC_CH0D1_PIO, timings, dummy);
        if (CS5535_BAD_PIO(timings))
                wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
-       return ata_pci_init_one(dev, ports, 1);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id cs5535[] = {
index 6ec049c3b1dcf4e0fbe03b374a0d17f69672a405..27b9f29c01e37eb784bf97e4184e00f8430aaed3 100644 (file)
@@ -125,10 +125,6 @@ static struct scsi_host_template cy82c693_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cy82c693_port_ops = {
@@ -169,14 +165,14 @@ static struct ata_port_operations cy82c693_port_ops = {
 
 static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &cy82c693_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &cy82c693_port_ops
        };
-       static struct ata_port_info *port_info[1] = { &info };
+       const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
 
        /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2.
           For the moment we don't handle the secondary. FIXME */
@@ -184,7 +180,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
        if (PCI_FUNC(pdev->devfn) != 1)
                return -ENODEV;
 
-       return ata_pci_init_one(pdev, port_info, 1);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id cy82c693[] = {
index d0f52e0349061779747fd622ce439a9a420463ca..079248a9b4604c49a017e253ac016f854f68e2d2 100644 (file)
@@ -247,10 +247,6 @@ static struct scsi_host_template efar_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations efar_ops = {
@@ -305,7 +301,7 @@ static const struct ata_port_operations efar_ops = {
 static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &efar_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -313,13 +309,13 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                .udma_mask      = 0x0f, /* UDMA 66 */
                .port_ops       = &efar_ops,
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id efar_pci_tbl[] = {
index e64e05e5c7fe26414ebbb3b7480ea764e95c985a..c6c8a8bb06d08af3447afb2f6b585c5f8a69b2c5 100644 (file)
@@ -331,10 +331,6 @@ static struct scsi_host_template hpt36x_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 /*
@@ -421,7 +417,7 @@ static void hpt36x_init_chipset(struct pci_dev *dev)
 
 static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info_hpt366 = {
+       static const struct ata_port_info info_hpt366 = {
                .sht = &hpt36x_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -429,7 +425,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x1f,
                .port_ops = &hpt366_port_ops
        };
-       struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366};
+       struct ata_port_info info = info_hpt366;
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        u32 class_rev;
        u32 reg1;
@@ -450,17 +447,17 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* info_hpt366 is safe against re-entry so we can scribble on it */
        switch((reg1 & 0x700) >> 8) {
                case 5:
-                       info_hpt366.private_data = &hpt366_40;
+                       info.private_data = &hpt366_40;
                        break;
                case 9:
-                       info_hpt366.private_data = &hpt366_25;
+                       info.private_data = &hpt366_25;
                        break;
                default:
-                       info_hpt366.private_data = &hpt366_33;
+                       info.private_data = &hpt366_33;
                        break;
        }
        /* Now kick off ATA set up */
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 #ifdef CONFIG_PM
index 1614e8c822a4ed7285f891b5353ea0cacbf95a9e..5a0a410654e2f8983c93479e27ae45afe6ad781d 100644 (file)
@@ -887,7 +887,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
 static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        /* HPT370 - UDMA100 */
-       static struct ata_port_info info_hpt370 = {
+       static const struct ata_port_info info_hpt370 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -896,7 +896,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt370_port_ops
        };
        /* HPT370A - UDMA100 */
-       static struct ata_port_info info_hpt370a = {
+       static const struct ata_port_info info_hpt370a = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -905,7 +905,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt370a_port_ops
        };
        /* HPT370 - UDMA100 */
-       static struct ata_port_info info_hpt370_33 = {
+       static const struct ata_port_info info_hpt370_33 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -914,7 +914,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt370_port_ops
        };
        /* HPT370A - UDMA100 */
-       static struct ata_port_info info_hpt370a_33 = {
+       static const struct ata_port_info info_hpt370a_33 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -923,7 +923,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt370a_port_ops
        };
        /* HPT371, 372 and friends - UDMA133 */
-       static struct ata_port_info info_hpt372 = {
+       static const struct ata_port_info info_hpt372 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -932,7 +932,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt372_port_ops
        };
        /* HPT371, 372 and friends - UDMA100 at 50MHz clock */
-       static struct ata_port_info info_hpt372_50 = {
+       static const struct ata_port_info info_hpt372_50 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -941,7 +941,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .port_ops = &hpt372_port_ops
        };
        /* HPT374 - UDMA133 */
-       static struct ata_port_info info_hpt374 = {
+       static const struct ata_port_info info_hpt374 = {
                .sht = &hpt37x_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -951,9 +951,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        };
 
        static const int MHz[4] = { 33, 40, 50, 66 };
-
-       struct ata_port_info *port_info[2];
-       struct ata_port_info *port;
+       const struct ata_port_info *port;
+       void *private_data = NULL;
+       struct ata_port_info port_info;
+       const struct ata_port_info *ppi[] = { &port_info, NULL };
 
        u8 irqmask;
        u32 class_rev;
@@ -1124,13 +1125,13 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        return -ENODEV;
                }
                if (clock_slot == 3)
-                       port->private_data = (void *)hpt37x_timings_66;
+                       private_data = (void *)hpt37x_timings_66;
                else
-                       port->private_data = (void *)hpt37x_timings_50;
+                       private_data = (void *)hpt37x_timings_50;
 
                printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
        } else {
-               port->private_data = (void *)chip_table->clocks[clock_slot];
+               private_data = (void *)chip_table->clocks[clock_slot];
                /*
                 *      Perform a final fixup. Note that we will have used the
                 *      DPLL on the HPT372 which means we don't have to worry
@@ -1144,9 +1145,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
        }
 
-       port_info[0] = port_info[1] = port;
        /* Now kick off ATA set up */
-       return ata_pci_init_one(dev, port_info, 2);
+       port_info = *port;
+       port_info.private_data = private_data;
+
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id hpt37x[] = {
index ea1037d6786028bbaaf1312a504ee407b66148e6..f25154aed75dbd9aab82df2bac041a71c16fecfd 100644 (file)
@@ -488,7 +488,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
 static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        /* HPT372N and friends - UDMA133 */
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &hpt3x2n_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -496,8 +496,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x7f,
                .port_ops = &hpt3x2n_port_ops
        };
-       struct ata_port_info *port_info[2];
-       struct ata_port_info *port = &info;
+       struct ata_port_info port = info;
+       const struct ata_port_info *ppi[] = { &port, NULL };
 
        u8 irqmask;
        u32 class_rev;
@@ -585,9 +585,9 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
        /* Set our private data up. We only need a few flags so we use
           it directly */
-       port->private_data = NULL;
+       port.private_data = NULL;
        if (pci_mhz > 60) {
-               port->private_data = (void *)PCI66;
+               port.private_data = (void *)PCI66;
                /*
                 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
                 * the MISC. register to stretch the UltraDMA Tss timing.
@@ -598,8 +598,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        /* Now kick off ATA set up */
-       port_info[0] = port_info[1] = port;
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id hpt3x2n[] = {
index ac28ec8c50aa61a19f03c704c843f50b8709ba05..bbabe7902fbb2c9376dbcb6cd6cd543e661539a1 100644 (file)
@@ -100,10 +100,6 @@ static struct scsi_host_template hpt3x3_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations hpt3x3_port_ops = {
@@ -175,7 +171,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev)
 
 static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &hpt3x3_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -183,11 +179,11 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x07,
                .port_ops = &hpt3x3_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        hpt3x3_init_chipset(dev);
        /* Now kick off ATA set up */
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 #ifdef CONFIG_PM
index 17bf9f3ed013b5c03fb1eaf15bc03bf3a143def9..a769952646e123158ded7705d86851ceaa727287 100644 (file)
@@ -257,10 +257,6 @@ static struct scsi_host_template it8213_sht = {
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations it8213_ops = {
@@ -315,7 +311,7 @@ static const struct ata_port_operations it8213_ops = {
 static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &it8213_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -323,14 +319,14 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
                .udma_mask      = 0x1f, /* UDMA 100 */
                .port_ops       = &it8213_ops,
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       /* Current IT8213 stuff is single port */
+       const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       /* Current IT8213 stuff is single port */
-       return ata_pci_init_one(pdev, port_info, 1);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id it8213_pci_tbl[] = {
index f1f8cec8c224aad4ae1375eb0ea551a810652966..ff9a6fd366577af8a36a83765ae66b231eb26dfd 100644 (file)
@@ -620,10 +620,6 @@ static struct scsi_host_template it821x_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations it821x_smart_port_ops = {
@@ -722,14 +718,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        u8 conf;
 
-       static struct ata_port_info info_smart = {
+       static const struct ata_port_info info_smart = {
                .sht = &it821x_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &it821x_smart_port_ops
        };
-       static struct ata_port_info info_passthru = {
+       static const struct ata_port_info info_passthru = {
                .sht = &it821x_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -737,8 +733,8 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask = 0x7f,
                .port_ops = &it821x_passthru_port_ops
        };
-       static struct ata_port_info *port_info[2];
 
+       const struct ata_port_info *ppi[] = { NULL, NULL };
        static char *mode[2] = { "pass through", "smart" };
 
        /* Force the card into bypass mode if so requested */
@@ -751,11 +747,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]);
        if (conf == 0)
-               port_info[0] = port_info[1] = &info_passthru;
+               ppi[0] = &info_passthru;
        else
-               port_info[0] = port_info[1] = &info_smart;
+               ppi[0] = &info_smart;
 
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index 420c343e57111107d88684557e8ea753f485fb39..b994351fbcd0a67cdbdb3e909cae49111f115ba9 100644 (file)
@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
-               if (ata_dev_ready(dev)) {
+               if (ata_dev_enabled(dev)) {
                        ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
                        dev->pio_mode = XFER_PIO_0;
                        dev->xfer_mode = XFER_PIO_0;
index 1daf78ac6efbb6c17b083231c1d7e95958a0361e..8d799e87f752548f0b5f9271800ad03f10a57b14 100644 (file)
@@ -138,10 +138,6 @@ static struct scsi_host_template jmicron_sht = {
        .slave_destroy          = ata_scsi_slave_destroy,
        /* Use standard CHS mapping rules */
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations jmicron_ops = {
@@ -195,7 +191,7 @@ static const struct ata_port_operations jmicron_ops = {
 
 static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &jmicron_sht,
                .flags  = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
 
@@ -205,9 +201,9 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 
                .port_ops       = &jmicron_ops,
        };
-       struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id jmicron_pci_tbl[] = {
index 837b7fe77dc7ff1e4a97b6265e91a22d28afa1c1..edbfe0dbbf7824188be84e2d41d3bfe8ed230eb6 100644 (file)
@@ -107,10 +107,6 @@ static struct scsi_host_template marvell_sht = {
        .slave_destroy          = ata_scsi_slave_destroy,
        /* Use standard CHS mapping rules */
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations marvell_ops = {
@@ -165,7 +161,7 @@ static const struct ata_port_operations marvell_ops = {
 
 static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &marvell_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
 
@@ -175,7 +171,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 
                .port_ops       = &marvell_ops,
        };
-       static struct ata_port_info info_sata = {
+       static const struct ata_port_info info_sata = {
                .sht            = &marvell_sht,
                /* Slave possible as its magically mapped not real */
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -186,13 +182,12 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
 
                .port_ops       = &marvell_ops,
        };
-       struct ata_port_info *port_info[2] = { &info, &info_sata };
-       int n_port = 2;
+       const struct ata_port_info *ppi[] = { &info, &info_sata };
 
        if (pdev->device == 0x6101)
-               n_port = 1;
+               ppi[1] = &ata_dummy_port_info;
 
-       return ata_pci_init_one(pdev, port_info, n_port);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id marvell_pci_tbl[] = {
index 9587a89f9683d98d46b4e359441b35dc598c11a9..368fac7d168be3cbb79a4ea1c6fa032360b1804c 100644 (file)
@@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx_ata_sht = {
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
index 3bfbd495f6434425e6d5cdb2b82c7618e6c9ce27..4ea42838297e68701343d86e7b05cd727b801128 100644 (file)
@@ -165,10 +165,6 @@ static struct scsi_host_template mpiix_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations mpiix_port_ops = {
index dbba5b77d79c907e0444a89a1732848cab277891..81f563458666b62d550df914d9547399f0a8b698 100644 (file)
@@ -37,10 +37,6 @@ static struct scsi_host_template netcell_sht = {
        .slave_destroy          = ata_scsi_slave_destroy,
        /* Use standard CHS mapping rules */
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations netcell_ops = {
@@ -96,7 +92,7 @@ static const struct ata_port_operations netcell_ops = {
 static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &netcell_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                /* Actually we don't really care about these as the
@@ -106,7 +102,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                .udma_mask      = 0x3f, /* UDMA 133 */
                .port_ops       = &netcell_ops,
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *port_info[] = { &info, NULL };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
@@ -116,7 +112,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        ata_pci_clear_simplex(pdev);
 
        /* And let the library code do the work */
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, port_info);
 }
 
 static const struct pci_device_id netcell_pci_tbl[] = {
index ebc58a907d26f3f8365961152a66fb9677182d54..ea70ec744879bbc1bc1cb8ec854d2ed5f7c1e5c6 100644 (file)
@@ -158,10 +158,6 @@ static struct scsi_host_template ns87410_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations ns87410_port_ops = {
@@ -195,14 +191,14 @@ static struct ata_port_operations ns87410_port_ops = {
 
 static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &ns87410_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x0F,
                .port_ops = &ns87410_port_ops
        };
-       static struct ata_port_info *port_info[2] = {&info, &info};
-       return ata_pci_init_one(dev, port_info, 2);
+       const struct ata_port_info *ppi[] = { &info, NULL };
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id ns87410[] = {
index 4d75d32e5826e1a45b7f6188224edbcdf6b19b3c..29c23ddd65504d8256ba44400cb321bd59c28882 100644 (file)
@@ -234,10 +234,6 @@ static struct scsi_host_template oldpiix_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations oldpiix_pata_ops = {
@@ -293,20 +289,20 @@ static const struct ata_port_operations oldpiix_pata_ops = {
 static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &oldpiix_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma1-2 */
                .port_ops       = &oldpiix_pata_ops,
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id oldpiix_pci_tbl[] = {
index 0af8a2c77cc970baea6733735639e85393cd35c6..1c44653e1e0653751a07075ac68f324f34ae83e7 100644 (file)
@@ -179,10 +179,6 @@ static struct scsi_host_template opti_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations opti_port_ops = {
@@ -220,19 +216,19 @@ static struct ata_port_operations opti_port_ops = {
 
 static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &opti_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &opti_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
        static int printed_version;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id opti[] = {
index 2843e480f2167a2d0fdd7937ce132b609c39260d..3093b02286ce93289a0bffd9934300b17472b734 100644 (file)
@@ -363,10 +363,6 @@ static struct scsi_host_template optidma_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations optidma_port_ops = {
@@ -486,14 +482,14 @@ done_nomsg:               /* Wrong chip revision */
 
 static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info_82c700 = {
+       static const struct ata_port_info info_82c700 = {
                .sht = &optidma_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &optidma_port_ops
        };
-       static struct ata_port_info info_82c700_udma = {
+       static const struct ata_port_info info_82c700_udma = {
                .sht = &optidma_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -501,8 +497,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x07,
                .port_ops = &optiplus_port_ops
        };
-       static struct ata_port_info *port_info[2];
-       struct ata_port_info *info = &info_82c700;
+       const struct ata_port_info *ppi[] = { &info_82c700, NULL };
        static int printed_version;
 
        if (!printed_version++)
@@ -514,10 +509,9 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        pci_clock = inb(0x1F5) & 1;             /* 0 = 33Mhz, 1 = 25Mhz */
 
        if (optiplus_with_udma(dev))
-               info = &info_82c700_udma;
+               ppi[0] = &info_82c700_udma;
 
-       port_info[0] = port_info[1] = info;
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id optidma[] = {
index 11245e331f779f80b5896e1478a9e20093cbbcde..4d44c7555db14c033eda97485f4fa15c923af0ba 100644 (file)
@@ -397,6 +397,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
        PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
index ee636beb05e132f7da4ca127d569702c5eb4d6fc..edbaf9d653b8a3a57e9b8b2de92301e735656d55 100644 (file)
@@ -244,10 +244,6 @@ static struct scsi_host_template pdc202xx_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations pdc2024x_port_ops = {
@@ -321,7 +317,7 @@ static struct ata_port_operations pdc2026x_port_ops = {
 
 static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info[3] = {
+       static const struct ata_port_info info[3] = {
                {
                        .sht = &pdc202xx_sht,
                        .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -348,9 +344,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                }
 
        };
-       static struct ata_port_info *port_info[2];
-
-       port_info[0] = port_info[1] = &info[id->driver_data];
+       const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
 
        if (dev->device == PCI_DEVICE_ID_PROMISE_20265) {
                struct pci_dev *bridge = dev->bus->self;
@@ -362,7 +356,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                                return -ENODEV;
                }
        }
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id pdc202xx[] = {
index a0a650c7f272042ae71458259fc1566aa66e91a9..1f6384895a4f71916dadd8b82bd1ca7429f22033 100644 (file)
@@ -48,6 +48,8 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse
        return 0;
 }
 
+static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
+
 static struct scsi_host_template pata_platform_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -91,7 +93,7 @@ static struct ata_port_operations pata_platform_port_ops = {
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
-       .port_start             = ata_port_start,
+       .port_start             = ata_dummy_ret0,
 };
 
 static void pata_platform_setup_port(struct ata_ioports *ioaddr,
index 1c54673e008d0a0d2f5e7c3f821ac260d162522d..ba96b54f5b873660c82ef3e997a038e5afc88410 100644 (file)
@@ -200,10 +200,6 @@ static struct scsi_host_template radisys_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations radisys_pata_ops = {
@@ -259,7 +255,7 @@ static const struct ata_port_operations radisys_pata_ops = {
 static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht            = &radisys_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -267,13 +263,13 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                .udma_mask      = 0x14, /* UDMA33/66 only */
                .port_ops       = &radisys_pata_ops,
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id radisys_pci_tbl[] = {
index 85c45290eeee9972c1c59b27737d43f03a6b9b5b..2bfd7ef42af5eb628d4db1b679f102dea33767b2 100644 (file)
@@ -40,7 +40,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
-               if (ata_dev_ready(dev)) {
+               if (ata_dev_enabled(dev)) {
                        /* We don't really care */
                        dev->pio_mode = XFER_PIO_0;
                        dev->xfer_mode = XFER_PIO_0;
@@ -69,10 +69,6 @@ static struct scsi_host_template rz1000_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations rz1000_port_ops = {
@@ -135,22 +131,20 @@ static int rz1000_fifo_disable(struct pci_dev *pdev)
 static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_port_info *port_info[2];
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &rz1000_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &rz1000_port_ops
        };
+       const struct ata_port_info *ppi[] = { &info, NULL };
 
        if (!printed_version++)
                printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
 
-       if (rz1000_fifo_disable(pdev) == 0) {
-               port_info[0] = &info;
-               port_info[1] = &info;
-               return ata_pci_init_one(pdev, port_info, 2);
-       }
+       if (rz1000_fifo_disable(pdev) == 0)
+               return ata_pci_init_one(pdev, ppi);
+
        printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
        /* Not safe to use so skip */
        return -ENODEV;
index 66e8ff467c8d1b7771ce282627070dc0a2e4d05f..225013ecf4b6cd5afdf8bb679f7067471f683a44 100644 (file)
@@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations sc1200_port_ops = {
@@ -247,7 +243,7 @@ static struct ata_port_operations sc1200_port_ops = {
 
 static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &sc1200_sht,
                .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -255,10 +251,10 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x07,
                .port_ops = &sc1200_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
-
        /* Can't enable port 2 yet, see top comments */
-       return ata_pci_init_one(dev, port_info, 1);
+       const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id sc1200[] = {
index 203f463ac39f8dc3ca0e4fd6ae595a564b6901ba..cca3aa225efeacfa16990346377e564f9a4c90af 100644 (file)
@@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations scc_pata_ops = {
index b6e020383dd960280ee3f28cc4c3bfe74a5ccc72..dee6e211949d8beefa7c7aacf2c1865c8a3e8120 100644 (file)
@@ -315,10 +315,6 @@ static struct scsi_host_template serverworks_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations serverworks_osb4_port_ops = {
@@ -479,8 +475,7 @@ static void serverworks_fixup_ht1000(struct pci_dev *pdev)
 
 static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       int ports = 2;
-       static struct ata_port_info info[4] = {
+       static const struct ata_port_info info[4] = {
                { /* OSB4 */
                        .sht = &serverworks_sht,
                        .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -511,8 +506,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
                        .port_ops = &serverworks_csb_port_ops
                }
        };
-       static struct ata_port_info *port_info[2];
-       struct ata_port_info *devinfo = &info[id->driver_data];
+       const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
 
        /* Force master latency timer to 64 PCI clocks */
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
@@ -521,7 +515,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
        if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
                /* Select non UDMA capable OSB4 if we can't do fixups */
                if ( serverworks_fixup_osb4(pdev) < 0)
-                       devinfo = &info[1];
+                       ppi[0] = &info[1];
        }
        /* setup CSB5/CSB6 : South Bridge and IDE option RAID */
        else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
@@ -531,11 +525,11 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
                 /* If the returned btr is the newer revision then
                    select the right info block */
                 if (serverworks_fixup_csb(pdev) == 3)
-                       devinfo = &info[3];
+                       ppi[0] = &info[3];
 
                /* Is this the 3rd channel CSB6 IDE ? */
                if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
-                       ports = 1;
+                       ppi[1] = &ata_dummy_port_info;
        }
        /* setup HT1000E */
        else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
@@ -544,8 +538,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
        if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
                ata_pci_clear_simplex(pdev);
 
-       port_info[0] = port_info[1] = devinfo;
-       return ata_pci_init_one(pdev, port_info, ports);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index a5886f061c0b424dd01d7c0eb33fec7440743e31..440e2cb6ee753dc4912707940943ddb9271ef567 100644 (file)
@@ -232,10 +232,6 @@ static struct scsi_host_template sil680_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static struct ata_port_operations sil680_port_ops = {
@@ -345,7 +341,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
 
 static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &sil680_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -353,7 +349,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask = 0x7f,
                .port_ops = &sil680_port_ops
        };
-       static struct ata_port_info info_slow = {
+       static const struct ata_port_info info_slow = {
                .sht = &sil680_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
@@ -361,7 +357,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask = 0x3f,
                .port_ops = &sil680_port_ops
        };
-       static struct ata_port_info *port_info[2] = {&info, &info};
+       const struct ata_port_info *ppi[] = { &info, NULL };
        static int printed_version;
 
        if (!printed_version++)
@@ -370,12 +366,12 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        switch(sil680_init_chip(pdev))
        {
                case 0:
-                       port_info[0] = port_info[1] = &info_slow;
+                       ppi[0] = &info_slow;
                        break;
                case 0x30:
                        return -ENODEV;
        }
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index f5838cc11728602e8445ba126499b821d12cbab4..f2231267e01120f918736a73fc7a18e3f0d3e2a5 100644 (file)
@@ -38,8 +38,8 @@
 #define DRV_VERSION    "0.5.1"
 
 struct sis_chipset {
-       u16 device;                     /* PCI host ID */
-       struct ata_port_info *info;     /* Info block */
+       u16 device;                             /* PCI host ID */
+       const struct ata_port_info *info;       /* Info block */
        /* Probably add family, cable detect type etc here to clean
           up code later */
 };
@@ -524,10 +524,6 @@ static struct scsi_host_template sis_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations sis_133_ops = {
@@ -700,7 +696,7 @@ static const struct ata_port_operations sis_old_ops = {
        .port_start             = ata_port_start,
 };
 
-static struct ata_port_info sis_info = {
+static const struct ata_port_info sis_info = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -708,7 +704,7 @@ static struct ata_port_info sis_info = {
        .udma_mask      = 0,
        .port_ops       = &sis_old_ops,
 };
-static struct ata_port_info sis_info33 = {
+static const struct ata_port_info sis_info33 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -716,35 +712,35 @@ static struct ata_port_info sis_info33 = {
        .udma_mask      = ATA_UDMA2,    /* UDMA 33 */
        .port_ops       = &sis_old_ops,
 };
-static struct ata_port_info sis_info66 = {
+static const struct ata_port_info sis_info66 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA4,    /* UDMA 66 */
        .port_ops       = &sis_66_ops,
 };
-static struct ata_port_info sis_info100 = {
+static const struct ata_port_info sis_info100 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA5,
        .port_ops       = &sis_100_ops,
 };
-static struct ata_port_info sis_info100_early = {
+static const struct ata_port_info sis_info100_early = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .udma_mask      = ATA_UDMA5,
        .pio_mask       = 0x1f, /* pio0-4 */
        .port_ops       = &sis_66_ops,
 };
-struct ata_port_info sis_info133 = {
+const struct ata_port_info sis_info133 = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
        .udma_mask      = ATA_UDMA6,
        .port_ops       = &sis_133_ops,
 };
-static struct ata_port_info sis_info133_early = {
+static const struct ata_port_info sis_info133_early = {
        .sht            = &sis_sht,
        .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
        .pio_mask       = 0x1f, /* pio0-4 */
@@ -827,8 +823,8 @@ static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       static struct ata_port_info *port_info[2];
-       struct ata_port_info *port;
+       struct ata_port_info port;
+       const struct ata_port_info *ppi[] = { &port, NULL };
        struct pci_dev *host = NULL;
        struct sis_chipset *chipset = NULL;
        struct sis_chipset *sets;
@@ -968,13 +964,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (chipset == NULL)
                return -ENODEV;
 
-       port = chipset->info;
-       port->private_data = chipset;
+       port = *chipset->info;
+       port.private_data = chipset;
 
        sis_fixup(pdev, chipset);
 
-       port_info[0] = port_info[1] = port;
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 static const struct pci_device_id sis_pci_tbl[] = {
index 9aeffdbe28293e72df734f5c0b72953f9051cdf1..f48491ad5f3aed221370787d2cf5319ad50baea4 100644 (file)
@@ -301,20 +301,22 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev)
 
 static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info_dma = {
+       static const struct ata_port_info info_dma = {
                .sht = &sl82c105_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &sl82c105_port_ops
        };
-       static struct ata_port_info info_early = {
+       static const struct ata_port_info info_early = {
                .sht = &sl82c105_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .port_ops = &sl82c105_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info_early, &info_early };
+       /* for now use only the first port */
+       const struct ata_port_info *ppi[] = { &info_early,
+                                              &ata_dummy_port_info };
        u32 val;
        int rev;
 
@@ -324,17 +326,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
                dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n");
        else if (rev <= 5)
                dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n");
-       else {
-               port_info[0] = &info_dma;
-               port_info[1] = &info_dma;
-       }
+       else
+               ppi[0] = &info_dma;
 
        pci_read_config_dword(dev, 0x40, &val);
        val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
        pci_write_config_dword(dev, 0x40, val);
 
-
-       return ata_pci_init_one(dev, port_info, 1); /* For now */
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id sl82c105[] = {
index 349887bf5b934d1f6f4f8ea5c63d57ef0bd073e1..b1d3076dfe5103cd56ffb57df39985c45e5c83a9 100644 (file)
@@ -194,10 +194,6 @@ static struct scsi_host_template triflex_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations triflex_port_ops = {
@@ -237,20 +233,20 @@ static struct ata_port_operations triflex_port_ops = {
 
 static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       static struct ata_port_info info = {
+       static const struct ata_port_info info = {
                .sht = &triflex_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
                .pio_mask = 0x1f,
                .mwdma_mask = 0x07,
                .port_ops = &triflex_port_ops
        };
-       static struct ata_port_info *port_info[2] = { &info, &info };
+       const struct ata_port_info *ppi[] = { &info, NULL };
        static int printed_version;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
-       return ata_pci_init_one(dev, port_info, 2);
+       return ata_pci_init_one(dev, ppi);
 }
 
 static const struct pci_device_id triflex[] = {
index 362beb2f489c1e67e80274101442b32e0d25fc4b..e4c71f76bd55ba701eea332594707880e3480f16 100644 (file)
@@ -301,10 +301,6 @@ static struct scsi_host_template via_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .resume                 = ata_scsi_device_resume,
-       .suspend                = ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations via_port_ops = {
@@ -425,7 +421,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
 static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        /* Early VIA without UDMA support */
-       static struct ata_port_info via_mwdma_info = {
+       static const struct ata_port_info via_mwdma_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -433,7 +429,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* Ditto with IRQ masking required */
-       static struct ata_port_info via_mwdma_info_borked = {
+       static const struct ata_port_info via_mwdma_info_borked = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -441,7 +437,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops_noirq,
        };
        /* VIA UDMA 33 devices (and borked 66) */
-       static struct ata_port_info via_udma33_info = {
+       static const struct ata_port_info via_udma33_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -450,7 +446,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 66 devices */
-       static struct ata_port_info via_udma66_info = {
+       static const struct ata_port_info via_udma66_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -459,7 +455,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* VIA UDMA 100 devices */
-       static struct ata_port_info via_udma100_info = {
+       static const struct ata_port_info via_udma100_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -468,7 +464,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .port_ops = &via_port_ops
        };
        /* UDMA133 with bad AST (All current 133) */
-       static struct ata_port_info via_udma133_info = {
+       static const struct ata_port_info via_udma133_info = {
                .sht = &via_sht,
                .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
                .pio_mask = 0x1f,
@@ -476,7 +472,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                .udma_mask = 0x7f,      /* FIXME: should check north bridge */
                .port_ops = &via_port_ops
        };
-       struct ata_port_info *port_info[2], *type;
+       struct ata_port_info type;
+       const struct ata_port_info *ppi[] = { &type, NULL };
        struct pci_dev *isa = NULL;
        const struct via_isa_bridge *config;
        static int printed_version;
@@ -521,25 +518,25 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        switch(config->flags & VIA_UDMA) {
                case VIA_UDMA_NONE:
                        if (config->flags & VIA_NO_UNMASK)
-                               type = &via_mwdma_info_borked;
+                               type = via_mwdma_info_borked;
                        else
-                               type = &via_mwdma_info;
+                               type = via_mwdma_info;
                        break;
                case VIA_UDMA_33:
-                       type = &via_udma33_info;
+                       type = via_udma33_info;
                        break;
                case VIA_UDMA_66:
-                       type = &via_udma66_info;
+                       type = via_udma66_info;
                        /* The 66 MHz devices require we enable the clock */
                        pci_read_config_dword(pdev, 0x50, &timing);
                        timing |= 0x80008;
                        pci_write_config_dword(pdev, 0x50, timing);
                        break;
                case VIA_UDMA_100:
-                       type = &via_udma100_info;
+                       type = via_udma100_info;
                        break;
                case VIA_UDMA_133:
-                       type = &via_udma133_info;
+                       type = via_udma133_info;
                        break;
                default:
                        WARN_ON(1);
@@ -554,10 +551,9 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        /* We have established the device type, now fire it up */
-       type->private_data = (void *)config;
+       type.private_data = (void *)config;
 
-       port_info[0] = port_info[1] = type;
-       return ata_pci_init_one(pdev, port_info, 2);
+       return ata_pci_init_one(pdev, ppi);
 }
 
 #ifdef CONFIG_PM
index b3b62e985f19e6dc1195b6a5890a94252a360f6d..bda5e7747c21002c0eead634c014e9848d95ce1b 100644 (file)
@@ -135,10 +135,6 @@ static struct scsi_host_template inic_sht = {
        .slave_configure        = inic_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const int scr_map[] = {
index a097595d4dc7a741d7bb01c8048085aced401abd..4cea3ef752264dd8fb6991ea1ddcf5e3ccc03bc6 100644 (file)
@@ -325,10 +325,6 @@ static struct scsi_host_template nv_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static struct scsi_host_template nv_adma_sht = {
@@ -347,10 +343,6 @@ static struct scsi_host_template nv_adma_sht = {
        .slave_configure        = nv_adma_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations nv_generic_ops = {
@@ -465,7 +457,7 @@ static const struct ata_port_operations nv_adma_ops = {
        .host_stop              = nv_adma_host_stop,
 };
 
-static struct ata_port_info nv_port_info[] = {
+static const struct ata_port_info nv_port_info[] = {
        /* generic */
        {
                .sht            = &nv_sht,
@@ -1545,7 +1537,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       const struct ata_port_info *ppi[2];
+       const struct ata_port_info *ppi[] = { NULL, NULL };
        struct ata_host *host;
        struct nv_host_priv *hpriv;
        int rc;
@@ -1573,8 +1565,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                type = ADMA;
        }
 
-       ppi[0] = ppi[1] = &nv_port_info[type];
-       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       ppi[0] = &nv_port_info[type];
+       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
index 0a1e417f309c5342aaaf763fa2ddc595e414fed7..e8483aadd11b7bcb059450c79c78eef1988cc180 100644 (file)
@@ -182,10 +182,6 @@ static struct scsi_host_template sil_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations sil_ops = {
index b97ee9f31aece7c8959f82c26b4a754af6e650ce..a69d78cd8e9b8e3cd931e764f7d43c2ad6c15587 100644 (file)
@@ -380,10 +380,6 @@ static struct scsi_host_template sil24_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations sil24_ops = {
index d8ee062e82fce91fafc91348296bc3ec75e930b9..ee66c5fa7ac8d51144923a6dc52aaf0afbf3f7f8 100644 (file)
@@ -129,7 +129,7 @@ static const struct ata_port_operations sis_ops = {
        .port_start             = ata_port_start,
 };
 
-static struct ata_port_info sis_port_info = {
+static const struct ata_port_info sis_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x7,
@@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        struct ata_port_info pi = sis_port_info;
-       const struct ata_port_info *ppi[2] = { &pi, &pi };
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ata_host *host;
        u32 genctl, val;
        u8 pmr;
@@ -335,7 +335,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
index f74e383de08303546259f0d1f817c77043788000..006f5e3526583168620f0b7a43e549d58cd68986 100644 (file)
@@ -125,7 +125,7 @@ static const struct ata_port_operations uli_ops = {
        .port_start             = ata_port_start,
 };
 
-static struct ata_port_info uli_port_info = {
+static const struct ata_port_info uli_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                          ATA_FLAG_IGN_SIMPLEX,
        .pio_mask       = 0x1f,         /* pio0-4 */
@@ -201,19 +201,33 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        n_ports = 2;
        if (board_idx == uli_5287)
                n_ports = 4;
-       rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host);
-       if (rc)
-               return rc;
+
+       /* allocate the host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host)
+               return -ENOMEM;
 
        hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
        host->private_data = hpriv;
 
+       /* the first two ports are standard SFF */
+       rc = ata_pci_init_native_host(host);
+       if (rc)
+               return rc;
+
+       rc = ata_pci_init_bmdma(host);
+       if (rc)
+               return rc;
+
        iomap = host->iomap;
 
        switch (board_idx) {
        case uli_5287:
+               /* If there are four, the last two live right after
+                * the standard SFF ports.
+                */
                hpriv->scr_cfg_addr[0] = ULI5287_BASE;
                hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
 
index 939c9246fdd1305b218e53712945b55974f901d0..d105d2c189d26547b7098bf88fb5e3ce72809745 100644 (file)
@@ -116,10 +116,6 @@ static struct scsi_host_template svia_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
-#ifdef CONFIG_PM
-       .suspend                = ata_scsi_device_suspend,
-       .resume                 = ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations vt6420_sata_ops = {
@@ -415,7 +411,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        struct ata_host *host;
        int rc;
 
-       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       rc = ata_pci_prepare_native_host(pdev, ppi, &host);
        if (rc)
                return rc;
        *r_host = host;
index 231da8fc22007ba9b155d8d7ed6c58b10461bff3..0f2208d8d5efdd087e361db8730c9bbeabb70fcc 100644 (file)
@@ -2,4 +2,4 @@
 struct ata_port_info;
 
 /* pata_sis.c */
-extern struct ata_port_info sis_info133;
+extern const struct ata_port_info sis_info133;
index 33687454eb324324f099fd5f79ad5a17caafd0f8..f5a47a48c3b4a18f7286e30c6a75507486da193a 100644 (file)
@@ -2,19 +2,22 @@
 # ATM device configuration
 #
 
-menu "ATM drivers"
+menuconfig ATM_DRIVERS
+       bool "ATM drivers"
        depends on NETDEVICES && ATM
+       default y
+
+if ATM_DRIVERS
 
 config ATM_DUMMY
        tristate "Dummy ATM driver"
-       depends on ATM
        help
          Dummy ATM driver. Useful for proxy signalling, testing,
          and development.  If unsure, say N.
 
 config ATM_TCP
        tristate "ATM over TCP"
-       depends on INET && ATM
+       depends on INET
        help
          ATM over TCP driver. Useful mainly for development and for
          experiments. If unsure, say N.
@@ -30,7 +33,7 @@ config ATM_LANAI
 
 config ATM_ENI
        tristate "Efficient Networks ENI155P"
-       depends on PCI && ATM
+       depends on PCI
        ---help---
          Driver for the Efficient Networks ENI155p series and SMC ATM
          Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
@@ -139,7 +142,7 @@ config ATM_ENI_BURST_RX_2W
 
 config ATM_FIRESTREAM
        tristate "Fujitsu FireStream (FS50/FS155) "
-       depends on PCI && ATM
+       depends on PCI
        help
          Driver for the Fujitsu FireStream 155 (MB86697) and
          FireStream 50 (MB86695) ATM PCI chips.
@@ -149,7 +152,7 @@ config ATM_FIRESTREAM
 
 config ATM_ZATM
        tristate "ZeitNet ZN1221/ZN1225"
-       depends on PCI && ATM
+       depends on PCI
        help
          Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
          adapters.
@@ -169,7 +172,7 @@ config ATM_ZATM_DEBUG
 
 config ATM_NICSTAR
        tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
-       depends on PCI && ATM && !64BIT
+       depends on PCI && !64BIT
        help
          The NICStAR chipset family is used in a large number of ATM NICs for
          25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
@@ -202,7 +205,7 @@ config ATM_NICSTAR_USE_IDT77105
 
 config ATM_IDT77252
        tristate "IDT 77252 (NICStAR II)"
-       depends on PCI && ATM
+       depends on PCI
        help
          Driver for the IDT 77252 ATM PCI chips.
 
@@ -237,7 +240,7 @@ config ATM_IDT77252_USE_SUNI
 
 config ATM_AMBASSADOR
        tristate "Madge Ambassador (Collage PCI 155 Server)"
-       depends on PCI && ATM
+       depends on PCI
        select BITREVERSE
        help
          This is a driver for ATMizer based ATM card produced by Madge
@@ -262,7 +265,7 @@ config ATM_AMBASSADOR_DEBUG
 
 config ATM_HORIZON
        tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
-       depends on PCI && ATM
+       depends on PCI
        help
          This is a driver for the Horizon chipset ATM adapter cards once
          produced by Madge Networks Ltd. Say Y (or M to compile as a module
@@ -286,7 +289,7 @@ config ATM_HORIZON_DEBUG
 
 config ATM_IA
        tristate "Interphase ATM PCI x575/x525/x531"
-       depends on PCI && ATM && !64BIT
+       depends on PCI && !64BIT
        ---help---
          This is a driver for the Interphase (i)ChipSAR adapter cards
          which include a variety of variants in term of the size of the
@@ -319,7 +322,7 @@ config ATM_IA_DEBUG
 
 config ATM_FORE200E_MAYBE
        tristate "FORE Systems 200E-series"
-       depends on (PCI || SBUS) && ATM
+       depends on PCI || SBUS
        ---help---
          This is a driver for the FORE Systems 200E-series ATM adapter
          cards. It simultaneously supports PCA-200E and SBA-200E models
@@ -436,7 +439,7 @@ config ATM_FORE200E
 
 config ATM_HE
        tristate "ForeRunner HE Series"
-       depends on PCI && ATM
+       depends on PCI
        help
          This is a driver for the Marconi ForeRunner HE-series ATM adapter
          cards. It simultaneously supports the 155 and 622 versions.
@@ -448,5 +451,4 @@ config ATM_HE_USE_SUNI
          Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
          HE cards.  This driver provides carrier detection some statistics.
 
-endmenu
-
+endif # ATM
index c9f0f250d78ff774a0608d393222ec7c6ce689ba..801abdd290669a092765191ef86450593dc23c2d 100644 (file)
@@ -268,7 +268,7 @@ static int __devinit aperture_valid(u64 aper, u32 size)
                printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
                return 0;
        }
-       if (aper + size > 0xffffffff) {
+       if ((u64)aper + size > 0x100000000ULL) {
                printk(KERN_ERR PFX "Aperture out of bounds\n");
                return 0;
        }
index 2f56e8c54897d5c55ca1caec974c95e43c787fd6..1b75b0b7d5429dae92918dc1987c813b1de25138 100644 (file)
@@ -203,8 +203,6 @@ scdrv_dispatch_event(char *event, int len)
        class = (code & EV_CLASS_MASK);
 
        if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) {
-               struct task_struct *p;
-
                if (snsc_shutting_down)
                        return;
 
index 3a80e0cc73699e9e24bcc6fb4382fab9cb5a9dec..624b21cef5b398617a543e69f48307169788f18b 100644 (file)
@@ -87,6 +87,14 @@ config VIDEO_TVEEPROM
        tristate
        depends on I2C
 
+config DAB
+       boolean "DAB adapters"
+       default y
+       ---help---
+         Allow selecting support for for Digital Audio Broadcasting (DAB)
+         Receiver adapters.
+
+if DAB
 config USB_DABUSB
        tristate "DABUSB driver"
        depends on USB
@@ -100,5 +108,6 @@ config USB_DABUSB
 
          To compile this driver as a module, choose M here: the
          module will be called dabusb.
+endif # DAB
 
 endmenu
index c578a529e7a8e910ea969b3fad2c58b28d95ca2d..8fa19939c2b6e5878bdfd29158d92a08be3dccf2 100644 (file)
@@ -5,4 +5,4 @@
 obj-y := common/
 obj-$(CONFIG_VIDEO_DEV) += video/
 obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB)       += dvb/
+obj-$(CONFIG_DVB_CORE)  += dvb/
index 86cbdbcf9d7db1f005e9cfa37a44b76088c59c61..ef3e54cd9407a9dab7c41bcff42f7d9129afdd0b 100644 (file)
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
        char *mem = vmalloc_32(length);
        int slen = 0;
 
-       if (NULL == mem) {
-               return NULL;
-       }
+       if (NULL == mem)
+               goto err_null;
 
-       if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
-               vfree(mem);
-               return NULL;
-       }
+       if (!(pt->slist = vmalloc_to_sg(mem, pages)))
+               goto err_free_mem;
 
-       if (saa7146_pgtable_alloc(pci, pt)) {
-               kfree(pt->slist);
-               pt->slist = NULL;
-               vfree(mem);
-               return NULL;
-       }
+       if (saa7146_pgtable_alloc(pci, pt))
+               goto err_free_slist;
 
-       slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
-       if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
-               return NULL;
-       }
+       pt->nents = pages;
+       slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
+       if (0 == slen)
+               goto err_free_pgtable;
+
+       if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
+               goto err_unmap_sg;
 
        return mem;
+
+err_unmap_sg:
+       pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+err_free_pgtable:
+       saa7146_pgtable_free(pci, pt);
+err_free_slist:
+       kfree(pt->slist);
+       pt->slist = NULL;
+err_free_mem:
+       vfree(mem);
+err_null:
+       return NULL;
+}
+
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
+{
+       pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+       saa7146_pgtable_free(pci, pt);
+       kfree(pt->slist);
+       pt->slist = NULL;
+       vfree(mem);
 }
 
 void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
                return;
        pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
        pt->cpu = NULL;
-       kfree(pt->slist);
-       pt->slist = NULL;
 }
 
 int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -528,6 +543,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
 EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
 EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
 EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
+EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
 EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
 
 EXPORT_SYMBOL_GPL(saa7146_setgpio);
index c18a5da6493470ae3e3af67342e08650970441e4..b4770aecc01db56afd363b9fcedbdfe49be90a20 100644 (file)
@@ -307,7 +307,6 @@ static int fops_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
 static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 /*
index a97c8f5e9a5d1dc13f6414106e9f75cc7ab9cd09..efd2b746815820e06698a209881e1d53c35d4cc8 100644 (file)
@@ -2,24 +2,16 @@
 # Multimedia device configuration
 #
 
-menu "Digital Video Broadcasting Devices"
+source "drivers/media/dvb/dvb-core/Kconfig"
 
-config DVB
-       bool "DVB For Linux"
-       depends on NET && INET
+menuconfig DVB_CAPTURE_DRIVERS
+       bool "DVB/ATSC adapters"
+       depends on DVB_CORE
+       default y
        ---help---
-         Support Digital Video Broadcasting hardware.  Enable this if you
-         own a DVB adapter and want to use it or if you compile Linux for
-         a digital SetTopBox.
-
-         API specs and user tools are available from <http://www.linuxtv.org/>.
+         Say Y to select Digital TV adapters
 
-         Please report problems regarding this driver to the LinuxDVB
-         mailing list.
-
-         If unsure say N.
-
-source "drivers/media/dvb/dvb-core/Kconfig"
+if DVB_CAPTURE_DRIVERS
 
 comment "Supported SAA7146 based PCI Adapters"
        depends on DVB_CORE && PCI && I2C
@@ -48,4 +40,4 @@ comment "Supported DVB Frontends"
        depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
 
-endmenu
+endif # DVB_CAPTURE_DRIVERS
index 1990eda10c469a52471495d8c865d7fa6d908985..e3e6839f807313da679dc2da28e992ad3c8b6e52 100644 (file)
@@ -1,12 +1,22 @@
 config DVB_CORE
-       tristate "DVB Core Support"
-       depends on DVB
+       tristate "DVB for Linux"
+       depends on NET && INET
        select CRC32
        help
+         Support Digital Video Broadcasting hardware.  Enable this if you
+         own a DVB adapter and want to use it or if you compile Linux for
+         a digital SetTopBox.
+
          DVB core utility functions for device handling, software fallbacks etc.
          Say Y when you have a DVB card and want to use it. Say Y if your want
          to build your drivers outside the kernel, but need the DVB core. All
          in-kernel drivers will select this automatically if needed.
+
+         API specs and user tools are available from <http://www.linuxtv.org/>.
+
+         Please report problems regarding this driver to the LinuxDVB
+         mailing list.
+
          If unsure say N.
 
 config DVB_CORE_ATTACH
index 97715f7514d666ae8ba61c9a1bcc9bd3b50ef402..403081689de1bdc30b1d339d7775f36cb479e133 100644 (file)
@@ -19,6 +19,7 @@
 #define USB_VID_COMPRO_UNK                     0x145f
 #define USB_VID_CYPRESS                                0x04b4
 #define USB_VID_DIBCOM                         0x10b8
+#define USB_VID_DPOSH                          0x1498
 #define USB_VID_DVICO                          0x0fe9
 #define USB_VID_EMPIA                          0xeb1a
 #define USB_VID_GENPIX                         0x09c0
@@ -61,6 +62,8 @@
 #define USB_PID_DIBCOM_STK7700P                                0x1e14
 #define USB_PID_DIBCOM_STK7700P_PC                     0x1e78
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
+#define USB_PID_DPOSH_M9206_COLD                       0x9206
+#define USB_PID_DPOSH_M9206_WARM                       0xa090
 #define USB_PID_UNIWILL_STK7700P                       0x6003
 #define USB_PID_GRANDTEC_DVBT_USB_COLD                 0x0fa0
 #define USB_PID_GRANDTEC_DVBT_USB_WARM                 0x0fa1
 #define USB_PID_MSI_DIGI_VOX_MINI_II                   0x1513
 #define USB_PID_OPERA1_COLD                            0x2830
 #define USB_PID_OPERA1_WARM                            0x3829
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD           0x0514
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM           0x0513
 
 
 #endif
index 0d721731a5241049c4e5130f63e0d4975458d792..6f824a569e14d5a2b4f9ca83f4e821d97a0437fe 100644 (file)
@@ -119,7 +119,7 @@ struct usb_data_stream_properties {
  * @caps: capabilities of the DVB USB device.
  * @pid_filter_count: number of PID filter position in the optional hardware
  *  PID-filter.
- * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
  *  device (not URB submitting/killing).
  * @pid_filter_ctrl: called to en/disable the PID filter, if any.
  * @pid_filter: called to set/unset a PID for filtering.
index 45d7bc214c18eb6e0e6f110079f0ba27209ea7cb..c546ddeda5d4fbd8d7e0f8a4dd8c40f131839cf0 100644 (file)
@@ -3,8 +3,8 @@
  * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
  *
  *     This program is free software; you can redistribute it and/or modify it
- *     under the terms of the GNU General Public License as published by the Free
- *     Software Foundation, version 2.
+ *     under the terms of the GNU General Public License as published by the
+ *     Free Software Foundation, version 2.
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
@@ -22,26 +22,7 @@ static int dvb_usb_m920x_debug;
 module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
 
-static struct dvb_usb_rc_key megasky_rc_keys [] = {
-       { 0x0, 0x12, KEY_POWER },
-       { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
-       { 0x0, 0x02, KEY_CHANNELUP },
-       { 0x0, 0x05, KEY_CHANNELDOWN },
-       { 0x0, 0x03, KEY_VOLUMEUP },
-       { 0x0, 0x06, KEY_VOLUMEDOWN },
-       { 0x0, 0x04, KEY_MUTE },
-       { 0x0, 0x07, KEY_OK }, /* TS */
-       { 0x0, 0x08, KEY_STOP },
-       { 0x0, 0x09, KEY_MENU }, /* swap */
-       { 0x0, 0x0a, KEY_REWIND },
-       { 0x0, 0x1b, KEY_PAUSE },
-       { 0x0, 0x1f, KEY_FASTFORWARD },
-       { 0x0, 0x0c, KEY_RECORD },
-       { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
-       { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
-};
-
-static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
+static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
                             u16 index, void *data, int size)
 {
        int ret;
@@ -55,14 +36,14 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
        }
 
        if (ret != size) {
-               deb_rc("m920x_read = no data\n");
+               deb("m920x_read = no data\n");
                return -EIO;
        }
 
        return 0;
 }
 
-static inline int m9206_write(struct usb_device *udev, u8 request,
+static inline int m920x_write(struct usb_device *udev, u8 request,
                              u16 value, u16 index)
 {
        int ret;
@@ -74,32 +55,40 @@ static inline int m9206_write(struct usb_device *udev, u8 request,
        return ret;
 }
 
-static int m9206_init(struct dvb_usb_device *d)
+static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
 {
        int ret = 0;
 
        /* Remote controller init. */
        if (d->props.rc_query) {
-               if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0)
-                       return ret;
+               deb("Initialising remote control\n");
+               while (rc_seq->address) {
+                       if ((ret = m920x_write(d->udev, M9206_CORE,
+                                              rc_seq->data,
+                                              rc_seq->address)) != 0) {
+                               deb("Initialising remote control failed\n");
+                               return ret;
+                       }
 
-               if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0)
-                       return ret;
+                       rc_seq++;
+               }
+
+               deb("Initialising remote control success\n");
        }
 
        return ret;
 }
 
-static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
-       struct m9206_state *m = d->priv;
+       struct m920x_state *m = d->priv;
        int i, ret = 0;
        u8 rc_state[2];
 
-       if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
                goto unlock;
 
-       if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
+       if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
                goto unlock;
 
        for (i = 0; i < d->props.rc_key_map_size; i++)
@@ -111,6 +100,14 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
                                *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
 
+                       case 0x88: /* framing error or "invalid code" */
+                       case 0x99:
+                       case 0xc0:
+                       case 0xd8:
+                               *state = REMOTE_NO_KEY_PRESSED;
+                               m->rep_count = 0;
+                               goto unlock;
+
                        case 0x93:
                        case 0x92:
                                m->rep_count = 0;
@@ -118,31 +115,32 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
                                goto unlock;
 
                        case 0x91:
-                               /* For comfort. */
+                               /* prevent immediate auto-repeat */
                                if (++m->rep_count > 2)
                                        *state = REMOTE_KEY_REPEAT;
+                               else
+                                       *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
 
                        default:
-                               deb_rc("Unexpected rc response %x\n", rc_state[0]);
+                               deb("Unexpected rc state %02x\n", rc_state[0]);
                                *state = REMOTE_NO_KEY_PRESSED;
                                goto unlock;
                        }
                }
 
        if (rc_state[1] != 0)
-               deb_rc("Unknown rc key %x\n", rc_state[1]);
+               deb("Unknown rc key %02x\n", rc_state[1]);
 
        *state = REMOTE_NO_KEY_PRESSED;
 
      unlock:
+ unlock:
 
        return ret;
 }
 
 /* I2C */
-static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-                         int num)
+static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
 {
        struct dvb_usb_device *d = i2c_get_adapdata(adap);
        int i, j;
@@ -155,33 +153,40 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
                return -EAGAIN;
 
        for (i = 0; i < num; i++) {
-               if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) ||
-                   msg[i].len == 0) {
-                       /* For a 0 byte message, I think sending the address to index 0x80|0x40
-                        * would be the correct thing to do.  However, zero byte messages are
-                        * only used for probing, and since we don't know how to get the slave's
-                        * ack, we can't probe. */
+               if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
+                       /* For a 0 byte message, I think sending the address
+                        * to index 0x80|0x40 would be the correct thing to
+                        * do.  However, zero byte messages are only used for
+                        * probing, and since we don't know how to get the
+                        * slave's ack, we can't probe. */
                        ret = -ENOTSUPP;
                        goto unlock;
                }
                /* Send START & address/RW bit */
                if (!(msg[i].flags & I2C_M_NOSTART)) {
-                       if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0)
+                       if ((ret = m920x_write(d->udev, M9206_I2C,
+                                       (msg[i].addr << 1) |
+                                       (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
                                goto unlock;
                        /* Should check for ack here, if we knew how. */
                }
                if (msg[i].flags & I2C_M_RD) {
                        for (j = 0; j < msg[i].len; j++) {
-                               /* Last byte of transaction? Send STOP, otherwise send ACK. */
-                               int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01;
-                               if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0)
+                               /* Last byte of transaction?
+                                * Send STOP, otherwise send ACK. */
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
+
+                               if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
+                                                     0x20 | stop,
+                                                     &msg[i].buf[j], 1)) != 0)
                                        goto unlock;
                        }
                } else {
                        for (j = 0; j < msg[i].len; j++) {
                                /* Last byte of transaction? Then send STOP. */
-                               int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00;
-                               if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
+                               int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
+
+                               if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
                                        goto unlock;
                                /* Should check for ack here too. */
                        }
@@ -189,25 +194,25 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
        }
        ret = num;
 
-unlock:
+ unlock:
        mutex_unlock(&d->i2c_mutex);
 
        return ret;
 }
 
-static u32 m9206_i2c_func(struct i2c_adapter *adapter)
+static u32 m920x_i2c_func(struct i2c_adapter *adapter)
 {
        return I2C_FUNC_I2C;
 }
 
-static struct i2c_algorithm m9206_i2c_algo = {
-       .master_xfer   = m9206_i2c_xfer,
-       .functionality = m9206_i2c_func,
+static struct i2c_algorithm m920x_i2c_algo = {
+       .master_xfer   = m920x_i2c_xfer,
+       .functionality = m920x_i2c_func,
 };
 
-
-static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
-                           int pid)
+/* pid filter */
+static int m920x_set_filter(struct dvb_usb_adapter *adap,
+                           int type, int idx, int pid)
 {
        int ret = 0;
 
@@ -216,18 +221,18 @@ static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
 
        pid |= 0x8000;
 
-       if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
+       if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
                return ret;
 
-       if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
+       if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
                return ret;
 
        return ret;
 }
 
-static int m9206_update_filters(struct dvb_usb_adapter *adap)
+static int m920x_update_filters(struct dvb_usb_adapter *adap)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
        int enabled = m->filtering_enabled;
        int i, ret = 0, filter = 0;
 
@@ -236,14 +241,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
                        enabled = 0;
 
        /* Disable all filters */
-       if ((ret = m9206_set_filter(adap, 0x81, 1, enabled)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0)
                return ret;
 
        for (i = 0; i < M9206_MAX_FILTERS; i++)
-               if ((ret = m9206_set_filter(adap, 0x81, i + 2, 0)) != 0)
+               if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0)
                        return ret;
 
-       if ((ret = m9206_set_filter(adap, 0x82, 0, 0x0)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0)
                return ret;
 
        /* Set */
@@ -252,40 +257,38 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
                        if (m->filters[i] == 0)
                                continue;
 
-                       if ((ret = m9206_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
+                       if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
                                return ret;
 
                        filter++;
                }
        }
 
-       if ((ret = m9206_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
+       if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
                return ret;
 
        return ret;
 }
 
-static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
 
        m->filtering_enabled = onoff ? 1 : 0;
 
-       return m9206_update_filters(adap);
+       return m920x_update_filters(adap);
 }
 
-static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
-                           int onoff)
+static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
 {
-       struct m9206_state *m = adap->dev->priv;
+       struct m920x_state *m = adap->dev->priv;
 
        m->filters[index] = onoff ? pid : 0;
 
-       return m9206_update_filters(adap);
+       return m920x_update_filters(adap);
 }
 
-static int m9206_firmware_download(struct usb_device *udev,
-                                  const struct firmware *fw)
+static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
 {
        u16 value, index, size;
        u8 read[4], *buff;
@@ -293,13 +296,13 @@ static int m9206_firmware_download(struct usb_device *udev,
 
        buff = kmalloc(65536, GFP_KERNEL);
 
-       if ((ret = m9206_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
+       if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
                goto done;
-       deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
+       deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
 
-       if ((ret = m9206_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
+       if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
                goto done;
-       deb_rc("%x\n", read[0]);
+       deb("%x\n", read[0]);
 
        for (pass = 0; pass < 2; pass++) {
                for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
@@ -317,11 +320,11 @@ static int m9206_firmware_download(struct usb_device *udev,
                                memcpy(buff, fw->data + i, size);
 
                                ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-                                           M9206_FW,
-                                           USB_TYPE_VENDOR | USB_DIR_OUT,
-                                           value, index, buff, size, 20);
+                                                     M9206_FW,
+                                                     USB_TYPE_VENDOR | USB_DIR_OUT,
+                                                     value, index, buff, size, 20);
                                if (ret != size) {
-                                       deb_rc("error while uploading fw!\n");
+                                       deb("error while uploading fw!\n");
                                        ret = -EIO;
                                        goto done;
                                }
@@ -330,7 +333,7 @@ static int m9206_firmware_download(struct usb_device *udev,
                        i += size;
                }
                if (i != fw->size) {
-                       deb_rc("bad firmware file!\n");
+                       deb("bad firmware file!\n");
                        ret = -EINVAL;
                        goto done;
                }
@@ -338,11 +341,11 @@ static int m9206_firmware_download(struct usb_device *udev,
 
        msleep(36);
 
-       /* m9206 will disconnect itself from the bus after this. */
-       (void) m9206_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
-       deb_rc("firmware uploaded!\n");
+       /* m920x will disconnect itself from the bus after this. */
+       (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
+       deb("firmware uploaded!\n");
 
      done:
+ done:
        kfree(buff);
 
        return ret;
@@ -362,7 +365,8 @@ static int m920x_identify_state(struct usb_device *udev,
        return 0;
 }
 
-static int megasky_mt352_demod_init(struct dvb_frontend *fe)
+/* demod configurations */
+static int m920x_mt352_demod_init(struct dvb_frontend *fe)
 {
        u8 config[] = { CONFIG, 0x3d };
        u8 clock[] = { CLOCK_CTL, 0x30 };
@@ -382,74 +386,174 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe)
        mt352_write(fe, unk1, ARRAY_SIZE(unk1));
        mt352_write(fe, unk2, ARRAY_SIZE(unk2));
 
-       deb_rc("Demod init!\n");
+       deb("Demod init!\n");
 
        return 0;
 }
 
-static struct mt352_config megasky_mt352_config = {
+static struct mt352_config m920x_mt352_config = {
        .demod_address = 0x0f,
        .no_tuner = 1,
-       .demod_init = megasky_mt352_demod_init,
+       .demod_init = m920x_mt352_demod_init,
+};
+
+static struct tda1004x_config m920x_tda10046_08_config = {
+       .demod_address = 0x08,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL,
+};
+
+static struct tda1004x_config m920x_tda10046_0b_config = {
+       .demod_address = 0x0b,
+       .invert = 0,
+       .invert_oclk = 0,
+       .ts_mode = TDA10046_TS_SERIAL,
+       .xtal_freq = TDA10046_XTAL_16M,
+       .if_freq = TDA10046_FREQ_045,
+       .agc_config = TDA10046_AGC_TDA827X,
+       .gpio_config = TDA10046_GPTRI,
+       .request_firmware = NULL, /* uses firmware EEPROM */
+};
+
+/* tuner configurations */
+static struct qt1010_config m920x_qt1010_config = {
+       .i2c_address = 0x62
 };
 
-static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+/* Callbacks for DVB USB */
+static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       deb_rc("megasky_frontend_attach!\n");
+       deb("%s\n",__FUNCTION__);
 
-       if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL)
+       if ((adap->fe = dvb_attach(mt352_attach,
+                                  &m920x_mt352_config,
+                                  &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
        return 0;
 }
 
-static struct qt1010_config megasky_qt1010_config = {
-       .i2c_address = 0x62
-};
-
-static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
-                      &megasky_qt1010_config) == NULL)
-               return -ENODEV;
+       deb("%s\n",__FUNCTION__);
+
+       if ((adap->fe = dvb_attach(tda10046_attach,
+                                  &m920x_tda10046_08_config,
+                                  &adap->dev->i2c_adap)) == NULL)
+               return -EIO;
 
        return 0;
 }
 
-static struct tda1004x_config digivox_tda10046_config = {
-       .demod_address = 0x08,
-       .invert = 0,
-       .invert_oclk = 0,
-       .ts_mode = TDA10046_TS_SERIAL,
-       .xtal_freq = TDA10046_XTAL_16M,
-       .if_freq = TDA10046_FREQ_045,
-       .agc_config = TDA10046_AGC_TDA827X,
-       .gpio_config = TDA10046_GPTRI,
-       .request_firmware = NULL,
-};
-
-static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
 {
-       deb_rc("digivox_tda10046_frontend_attach!\n");
+       deb("%s\n",__FUNCTION__);
 
-       if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config,
+       if ((adap->fe = dvb_attach(tda10046_attach,
+                                  &m920x_tda10046_0b_config,
                                   &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
        return 0;
 }
 
-static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
 {
-       if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap,
-                      NULL) == NULL)
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
                return -ENODEV;
+
        return 0;
 }
 
+static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       deb("%s\n",__FUNCTION__);
+
+       if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
+               return -ENODEV;
+
+       return 0;
+}
+
+/* device-specific initialization */
+static struct m920x_inits megasky_rc_init [] = {
+       { M9206_RC_INIT2, 0xa8 },
+       { M9206_RC_INIT1, 0x51 },
+       { } /* terminating entry */
+};
+
+static struct m920x_inits tvwalkertwin_rc_init [] = {
+       { M9206_RC_INIT2, 0x00 },
+       { M9206_RC_INIT1, 0xef },
+       { 0xff28,         0x00 },
+       { 0xff23,         0x00 },
+       { 0xff21,         0x30 },
+       { } /* terminating entry */
+};
+
+/* ir keymaps */
+static struct dvb_usb_rc_key megasky_rc_keys [] = {
+       { 0x0, 0x12, KEY_POWER },
+       { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
+       { 0x0, 0x02, KEY_CHANNELUP },
+       { 0x0, 0x05, KEY_CHANNELDOWN },
+       { 0x0, 0x03, KEY_VOLUMEUP },
+       { 0x0, 0x06, KEY_VOLUMEDOWN },
+       { 0x0, 0x04, KEY_MUTE },
+       { 0x0, 0x07, KEY_OK }, /* TS */
+       { 0x0, 0x08, KEY_STOP },
+       { 0x0, 0x09, KEY_MENU }, /* swap */
+       { 0x0, 0x0a, KEY_REWIND },
+       { 0x0, 0x1b, KEY_PAUSE },
+       { 0x0, 0x1f, KEY_FASTFORWARD },
+       { 0x0, 0x0c, KEY_RECORD },
+       { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
+       { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
+};
+
+static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
+       { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
+       { 0x0, 0x02, KEY_CAMERA }, /* snapshot */
+       { 0x0, 0x03, KEY_MUTE },
+       { 0x0, 0x04, KEY_REWIND },
+       { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
+       { 0x0, 0x06, KEY_FASTFORWARD },
+       { 0x0, 0x07, KEY_RECORD },
+       { 0x0, 0x08, KEY_STOP },
+       { 0x0, 0x09, KEY_TIME }, /* Timeshift */
+       { 0x0, 0x0c, KEY_COFFEE }, /* Recall */
+       { 0x0, 0x0e, KEY_CHANNELUP },
+       { 0x0, 0x12, KEY_POWER },
+       { 0x0, 0x15, KEY_MENU }, /* source */
+       { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
+       { 0x0, 0x1a, KEY_CHANNELDOWN },
+       { 0x0, 0x1b, KEY_VOLUMEDOWN },
+       { 0x0, 0x1e, KEY_VOLUMEUP },
+};
+
 /* DVB USB Driver stuff */
 static struct dvb_usb_device_properties megasky_properties;
 static struct dvb_usb_device_properties digivox_mini_ii_properties;
+static struct dvb_usb_device_properties tvwalkertwin_properties;
+static struct dvb_usb_device_properties dposh_properties;
 
 static int m920x_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
@@ -457,19 +561,57 @@ static int m920x_probe(struct usb_interface *intf,
        struct dvb_usb_device *d;
        struct usb_host_interface *alt;
        int ret;
+       struct m920x_inits *rc_init_seq = NULL;
+       int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
 
-       deb_rc("Probed!\n");
+       deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
 
-       if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) ||
-           ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0))
-               goto found;
+       if (bInterfaceNumber == 0) {
+               /* Single-tuner device, or first interface on
+                * multi-tuner device
+                */
 
-       return ret;
+               if ((ret = dvb_usb_device_init(intf, &megasky_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       rc_init_seq = megasky_rc_init;
+                       goto found;
+               }
+
+               if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       /* No remote control, so no rc_init_seq */
+                       goto found;
+               }
+
+               /* This configures both tuners on the TV Walker Twin */
+               if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       rc_init_seq = tvwalkertwin_rc_init;
+                       goto found;
+               }
+
+               if ((ret = dvb_usb_device_init(intf, &dposh_properties,
+                                              THIS_MODULE, &d)) == 0) {
+                       /* Remote controller not supported yet. */
+                       goto found;
+               }
+
+               return ret;
+       } else {
+               /* Another interface on a multi-tuner device */
 
-found:
+               /* The LifeView TV Walker Twin gets here, but struct
+                * tvwalkertwin_properties already configured both
+                * tuners, so there is nothing for us to do here
+                */
+
+               return -ENODEV;
+       }
+
+ found:
        alt = usb_altnum_to_altsetting(intf, 1);
        if (alt == NULL) {
-               deb_rc("No alt found!\n");
+               deb("No alt found!\n");
                return -ENODEV;
        }
 
@@ -478,7 +620,7 @@ found:
        if (ret < 0)
                return ret;
 
-       if ((ret = m9206_init(d)) != 0)
+       if ((ret = m920x_init(d, rc_init_seq)) != 0)
                return ret;
 
        return ret;
@@ -488,6 +630,12 @@ static struct usb_device_id m920x_table [] = {
                { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
                { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
                             USB_PID_MSI_DIGI_VOX_MINI_II) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
+               { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+                            USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
+               { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
                { }             /* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -497,14 +645,14 @@ static struct dvb_usb_device_properties megasky_properties = {
 
        .usb_ctrl = DEVICE_SPECIFIC,
        .firmware = "dvb-usb-megasky-02.fw",
-       .download_firmware = m9206_firmware_download,
+       .download_firmware = m920x_firmware_download,
 
        .rc_interval      = 100,
        .rc_key_map       = megasky_rc_keys,
        .rc_key_map_size  = ARRAY_SIZE(megasky_rc_keys),
-       .rc_query         = m9206_rc_query,
+       .rc_query         = m920x_rc_query,
 
-       .size_of_priv     = sizeof(struct m9206_state),
+       .size_of_priv     = sizeof(struct m920x_state),
 
        .identify_state   = m920x_identify_state,
        .num_adapters = 1,
@@ -513,11 +661,11 @@ static struct dvb_usb_device_properties megasky_properties = {
                        DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 
                .pid_filter_count = 8,
-               .pid_filter       = m9206_pid_filter,
-               .pid_filter_ctrl  = m9206_pid_filter_ctrl,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
 
-               .frontend_attach  = megasky_mt352_frontend_attach,
-               .tuner_attach     = megasky_qt1010_tuner_attach,
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
 
                .stream = {
                        .type = USB_BULK,
@@ -530,7 +678,7 @@ static struct dvb_usb_device_properties megasky_properties = {
                        }
                },
        }},
-       .i2c_algo         = &m9206_i2c_algo,
+       .i2c_algo         = &m920x_i2c_algo,
 
        .num_device_descs = 1,
        .devices = {
@@ -546,22 +694,22 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
 
        .usb_ctrl = DEVICE_SPECIFIC,
        .firmware = "dvb-usb-digivox-02.fw",
-       .download_firmware = m9206_firmware_download,
+       .download_firmware = m920x_firmware_download,
 
-       .size_of_priv     = sizeof(struct m9206_state),
+       .size_of_priv     = sizeof(struct m920x_state),
 
        .identify_state   = m920x_identify_state,
        .num_adapters = 1,
        .adapter = {{
                .caps = DVB_USB_ADAP_HAS_PID_FILTER |
-               DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 
                .pid_filter_count = 8,
-               .pid_filter       = m9206_pid_filter,
-               .pid_filter_ctrl  = m9206_pid_filter_ctrl,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
 
-               .frontend_attach  = digivox_tda10046_frontend_attach,
-               .tuner_attach     = digivox_tda8275_tuner_attach,
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
 
                .stream = {
                        .type = USB_BULK,
@@ -574,7 +722,7 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
                        }
                },
        }},
-       .i2c_algo         = &m9206_i2c_algo,
+       .i2c_algo         = &m920x_i2c_algo,
 
        .num_device_descs = 1,
        .devices = {
@@ -585,6 +733,122 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
        }
 };
 
+/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
+ *
+ * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
+ * TDA10046 #0 is located at i2c address 0x08
+ * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working)
+ * TDA8275A #0 is located at i2c address 0x60
+ * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working)
+ */
+static struct dvb_usb_device_properties tvwalkertwin_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-tvwalkert.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .rc_interval      = 100,
+       .rc_key_map       = tvwalkertwin_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(tvwalkertwin_rc_keys),
+       .rc_query         = m920x_rc_query,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_08_frontend_attach,
+               .tuner_attach     = m920x_tda8275_60_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               }},{
+               .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+                       DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+               .pid_filter_count = 8,
+               .pid_filter       = m920x_pid_filter,
+               .pid_filter_ctrl  = m920x_pid_filter_ctrl,
+
+               .frontend_attach  = m920x_tda10046_0b_frontend_attach,
+               .tuner_attach     = m920x_tda8275_61_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x82,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               },
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   .name = "LifeView TV Walker Twin DVB-T USB2.0",
+                   .cold_ids = { &m920x_table[2], NULL },
+                   .warm_ids = { &m920x_table[3], NULL },
+               },
+       }
+};
+
+static struct dvb_usb_device_properties dposh_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl = DEVICE_SPECIFIC,
+       .firmware = "dvb-usb-dposh-01.fw",
+       .download_firmware = m920x_firmware_download,
+
+       .size_of_priv     = sizeof(struct m920x_state),
+
+       .identify_state   = m920x_identify_state,
+       .num_adapters = 1,
+       .adapter = {{
+               /* Hardware pid filters don't work with this device/firmware */
+
+               .frontend_attach  = m920x_mt352_frontend_attach,
+               .tuner_attach     = m920x_qt1010_tuner_attach,
+
+               .stream = {
+                       .type = USB_BULK,
+                       .count = 8,
+                       .endpoint = 0x81,
+                       .u = {
+                                .bulk = {
+                                        .buffersize = 512,
+                                }
+                       }
+               },
+       }},
+       .i2c_algo         = &m920x_i2c_algo,
+
+       .num_device_descs = 1,
+       .devices = {
+                {   .name = "Dposh DVB-T USB2.0",
+                    .cold_ids = { &m920x_table[4], NULL },
+                    .warm_ids = { &m920x_table[5], NULL },
+                },
+        }
+};
+
 static struct usb_driver m920x_driver = {
        .name           = "dvb_usb_m920x",
        .probe          = m920x_probe,
@@ -615,6 +879,11 @@ module_init (m920x_module_init);
 module_exit (m920x_module_exit);
 
 MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / Uli m920x");
+MODULE_DESCRIPTION("DVB Driver for ULI M920x");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
index 7dd3db65c80eeba1a573be349bd9b6675fa4c968..2c8942d042226e51908089523517f18aac934c33 100644 (file)
@@ -4,7 +4,7 @@
 #define DVB_USB_LOG_PREFIX "m920x"
 #include "dvb-usb.h"
 
-#define deb_rc(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
+#define deb(args...)   dprintk(dvb_usb_m920x_debug,0x01,args)
 
 #define M9206_CORE     0x22
 #define M9206_RC_STATE 0xff51
@@ -59,9 +59,18 @@ What any other bits might mean, or how to get the slave's ACK/NACK
 response to a write, is unknown.
 */
 
-struct m9206_state {
+struct m920x_state {
        u16 filters[M9206_MAX_FILTERS];
        int filtering_enabled;
        int rep_count;
 };
+
+/* Initialisation data for the m920x
+ */
+
+struct m920x_inits {
+       u16 address;
+       u8  data;
+};
+
 #endif
index 3ecb2e0ce80f7ec986023b014a8a249b1fe7dadb..c3fdc7cd094e33f41c4e2c34f4ec7b565233d2e6 100644 (file)
@@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
                                    struct dvb_diseqc_master_cmd *m)
 {
-       //struct vp702x_fe_state *st = fe->demodulator_priv;
-       u8 cmd[8];//,ibuf[10];
+       struct vp702x_fe_state *st = fe->demodulator_priv;
+       u8 cmd[8],ibuf[10];
        memset(cmd,0,8);
 
        deb_fe("%s\n",__FUNCTION__);
@@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
        memcpy(&cmd[3], m->msg, m->msg_len);
        cmd[7] = vp702x_chksum(cmd,0,7);
 
-//     vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+       vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
 
-//     if (ibuf[2] == 0 && ibuf[3] == 0)
-//             deb_fe("diseqc cmd failed.\n");
-//     else
-//             deb_fe("diseqc cmd succeeded.\n");
+       if (ibuf[2] == 0 && ibuf[3] == 0)
+               deb_fe("diseqc cmd failed.\n");
+       else
+               deb_fe("diseqc cmd succeeded.\n");
 
        return 0;
 }
index 058df5c100348b89657c79ede7772054444ee42f..08a2599ed74a7463293ae0e8858642fd6b495d84 100644 (file)
@@ -293,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
         *     but no packets have been transfered.
         * [2] Sometimes (actually very often) NBPACKETS stays at zero
         *     although one packet has been transfered.
+        * [3] Sometimes (actually rarely), the card gets into an erroneous
+        *     mode where it continuously generates interrupts, claiming it
+        *     has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+        *     has been transfered. Only a reset seems to solve this
         */
        if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
                unsigned int i = 0;
                while (pluto->dma_buf[i] == 0x47)
                        i += 188;
                nbpackets = i / 188;
+               if (i == 0) {
+                       pluto_reset_ts(pluto, 1);
+                       dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+               }
        }
 
        dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
index 67becdd4db609e87f3584c2bdd95c5a8961cfb2c..ef1108c0bf11005167eb6b6b225ac4a890465369 100644 (file)
@@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data)
        if (!budget->feeding1 || (newdma == olddma))
                return;
 
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
 #if 0
        /* track rps1 activity */
        printk("vpeirq: %02x Event Counter 1 0x%04x\n",
@@ -2679,8 +2682,8 @@ err_iobuf_vfree_6:
 err_pci_free_5:
        pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
 err_saa71466_vfree_4:
-       if (!av7110->grabbing)
-               saa7146_pgtable_free(pdev, &av7110->pt);
+       if (av7110->grabbing)
+               saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
 err_i2c_del_3:
        i2c_del_adapter(&av7110->i2c_adap);
 err_dvb_unregister_adapter_2:
@@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
                SAA7146_ISR_CLEAR(saa, MASK_10);
                msleep(50);
                tasklet_kill(&av7110->vpe_tasklet);
-               saa7146_pgtable_free(saa->pci, &av7110->pt);
+               saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
        }
        av7110_exit_v4l(av7110);
 
index 4ed4599ce816b78be6c5f3527ceb9f84028a2e8e..9d42f88ebb0ed048db14f3f5089da90668381816 100644 (file)
@@ -904,7 +904,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
                band = 1;
        } else if (tuner_frequency < 200000000) {
                cp = 6;
-               band = 2;
+               band = 1;
        } else if (tuner_frequency < 290000000) {
                cp = 3;
                band = 2;
index 6b97dc1e6b6561277f867419942f8f16f214e5c3..2557ac9620d02f20794955c6a0f26c87d8df7d19 100644 (file)
@@ -195,6 +195,9 @@ static void vpeirq(unsigned long data)
        u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
        u32 count;
 
+       /* Ensure streamed PCI data is synced to CPU */
+       pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
        /* nearest lower position divisible by 188 */
        newdma -= newdma % 188;
 
@@ -504,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        strcpy(budget->i2c_adap.name, budget->card->name);
 
        if (i2c_add_adapter(&budget->i2c_adap) < 0) {
-               dvb_unregister_adapter(&budget->dvb_adapter);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_dvb_unregister;
        }
 
        ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
 
-       if (NULL ==
-           (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
+       budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+       if (NULL == budget->grabbing) {
                ret = -ENOMEM;
-               goto err;
+               goto err_del_i2c;
        }
 
        saa7146_write(dev, PCI_BT_V1, 0x001c0000);
@@ -526,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
        if (bi->type != BUDGET_FS_ACTIVY)
                saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
 
-       if (budget_register(budget) == 0) {
-               return 0;
-       }
-err:
-       i2c_del_adapter(&budget->i2c_adap);
+       if (budget_register(budget) == 0)
+               return 0; /* Everything OK */
+
+       /* An error occurred, cleanup resources */
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
 
-       vfree(budget->grabbing);
+err_del_i2c:
+       i2c_del_adapter(&budget->i2c_adap);
 
+err_dvb_unregister:
        dvb_unregister_adapter(&budget->dvb_adapter);
 
        return ret;
@@ -555,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget)
 
        budget_unregister(budget);
 
-       i2c_del_adapter(&budget->i2c_adap);
-
-       dvb_unregister_adapter(&budget->dvb_adapter);
-
        tasklet_kill(&budget->vpe_tasklet);
 
-       saa7146_pgtable_free(dev->pci, &budget->pt);
+       saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
 
-       vfree(budget->grabbing);
+       i2c_del_adapter(&budget->i2c_adap);
+
+       dvb_unregister_adapter(&budget->dvb_adapter);
 
        return 0;
 }
index af66a5d5ecd8b484af9ad661f59071c4714f8d5b..a6ac82a609d40c12315b9d60d9ef3a156fbafdd0 100644 (file)
@@ -2,8 +2,14 @@
 # Multimedia Video device configuration
 #
 
-menu "Radio Adapters"
+menuconfig RADIO_ADAPTERS
+       bool "Radio Adapters"
        depends on VIDEO_DEV
+       default y
+       ---help---
+         Say Y here to enable selecting AM/FM radio adapters.
+
+if RADIO_ADAPTERS
 
 config RADIO_CADET
        tristate "ADS Cadet AM/FM Tuner"
@@ -328,4 +334,5 @@ config USB_DSBR
 
          To compile this driver as a module, choose M here: the
          module will be called dsbr100.
-endmenu
+
+endif # RADIO_ADAPTERS
index 449df1bb00d3050914a219a8ee99d8fca498cb48..3bd07f7e377489198ca539deee8e3401ffa5056a 100644 (file)
 
  History:
 
+ Version 0.42:
+       Converted dsbr100 to use video_ioctl2
+       by Douglas Landgraf <dougsland@gmail.com>
+
  Version 0.41-ac1:
        Alan Cox: Some cleanups and fixes
 
@@ -121,8 +125,6 @@ devices, that would be 76 and 91.  */
 static int usb_dsbr100_probe(struct usb_interface *intf,
                             const struct usb_device_id *id);
 static void usb_dsbr100_disconnect(struct usb_interface *intf);
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
-                            unsigned int cmd, unsigned long arg);
 static int usb_dsbr100_open(struct inode *inode, struct file *file);
 static int usb_dsbr100_close(struct inode *inode, struct file *file);
 
@@ -142,26 +144,6 @@ struct dsbr100_device {
 };
 
 
-/* File system interface */
-static const struct file_operations usb_dsbr100_fops = {
-       .owner =        THIS_MODULE,
-       .open =         usb_dsbr100_open,
-       .release =      usb_dsbr100_close,
-       .ioctl =        usb_dsbr100_ioctl,
-       .compat_ioctl = v4l_compat_ioctl32,
-       .llseek =       no_llseek,
-};
-
-/* V4L interface */
-static struct video_device dsbr100_videodev_template=
-{
-       .owner =        THIS_MODULE,
-       .name =         "D-Link DSB-R 100",
-       .type =         VID_TYPE_TUNER,
-       .fops =         &usb_dsbr100_fops,
-       .release = video_device_release,
-};
-
 static struct usb_device_id usb_dsbr100_device_table [] = {
        { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
        { }                                             /* Terminating entry */
@@ -252,37 +234,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
 
 /* USB subsystem interface begins here */
 
-/* check if the device is present and register with v4l and
-usb if it is */
-static int usb_dsbr100_probe(struct usb_interface *intf,
-                        const struct usb_device_id *id)
-{
-       struct dsbr100_device *radio;
-
-       if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
-               return -ENOMEM;
-       if (!(radio->videodev = video_device_alloc())) {
-               kfree(radio);
-               return -ENOMEM;
-       }
-       memcpy(radio->videodev, &dsbr100_videodev_template,
-               sizeof(dsbr100_videodev_template));
-       radio->removed = 0;
-       radio->users = 0;
-       radio->usbdev = interface_to_usbdev(intf);
-       radio->curfreq = FREQ_MIN*FREQ_MUL;
-       video_set_drvdata(radio->videodev, radio);
-       if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
-               radio_nr)) {
-               warn("Could not register video device");
-               video_device_release(radio->videodev);
-               kfree(radio);
-               return -EIO;
-       }
-       usb_set_intfdata(intf, radio);
-       return 0;
-}
-
 /* handle unplugging of the device, release data structures
 if nothing keeps us from doing it.  If something is still
 keeping us busy, the release callback of v4l will take care
@@ -307,133 +258,147 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
 }
 
 
-/* Video for Linux interface */
+static int vidioc_querycap(struct file *file, void *priv,
+                                       struct v4l2_capability *v)
+{
+       strlcpy(v->driver, "dsbr100", sizeof(v->driver));
+       strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
+       sprintf(v->bus_info, "ISA");
+       v->version = RADIO_VERSION;
+       v->capabilities = V4L2_CAP_TUNER;
+       return 0;
+}
 
-static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
 {
-       struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
+
+       if (v->index > 0)
+               return -EINVAL;
+
+       dsbr100_getstat(radio);
+       strcpy(v->name, "FM");
+       v->type = V4L2_TUNER_RADIO;
+       v->rangelow = FREQ_MIN*FREQ_MUL;
+       v->rangehigh = FREQ_MAX*FREQ_MUL;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->capability = V4L2_TUNER_CAP_LOW;
+       if(radio->stereo)
+               v->audmode = V4L2_TUNER_MODE_STEREO;
+       else
+               v->audmode = V4L2_TUNER_MODE_MONO;
+       v->signal = 0xffff;     /* We can't get the signal strength */
+       return 0;
+}
 
-       if (!radio)
-               return -EIO;
+static int vidioc_s_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
+{
+       if (v->index > 0)
+               return -EINVAL;
 
-       switch(cmd) {
-               case VIDIOC_QUERYCAP:
-               {
-                       struct v4l2_capability *v = arg;
-                       memset(v,0,sizeof(*v));
-                       strlcpy(v->driver, "dsbr100", sizeof (v->driver));
-                       strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card));
-                       sprintf(v->bus_info,"ISA");
-                       v->version = RADIO_VERSION;
-                       v->capabilities = V4L2_CAP_TUNER;
+       return 0;
+}
 
-                       return 0;
-               }
-               case VIDIOC_G_TUNER:
-               {
-                       struct v4l2_tuner *v = arg;
+static int vidioc_s_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       if (v->index > 0)
-                               return -EINVAL;
+       radio->curfreq = f->frequency;
+       if (dsbr100_setfreq(radio, radio->curfreq)==-1)
+               warn("Set frequency failed");
+       return 0;
+}
 
-                       dsbr100_getstat(radio);
+static int vidioc_g_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       memset(v,0,sizeof(*v));
-                       strcpy(v->name, "FM");
-                       v->type = V4L2_TUNER_RADIO;
+       f->type = V4L2_TUNER_RADIO;
+       f->frequency = radio->curfreq;
+       return 0;
+}
 
-                       v->rangelow = FREQ_MIN*FREQ_MUL;
-                       v->rangehigh = FREQ_MAX*FREQ_MUL;
-                       v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
-                       v->capability=V4L2_TUNER_CAP_LOW;
-                       if(radio->stereo)
-                               v->audmode = V4L2_TUNER_MODE_STEREO;
-                       else
-                               v->audmode = V4L2_TUNER_MODE_MONO;
-                       v->signal = 0xFFFF;     /* We can't get the signal strength */
+static int vidioc_queryctrl(struct file *file, void *priv,
+                               struct v4l2_queryctrl *qc)
+{
+       int i;
 
+       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+               if (qc->id && qc->id == radio_qctrl[i].id) {
+                       memcpy(qc, &(radio_qctrl[i]),
+                                               sizeof(*qc));
                        return 0;
                }
-               case VIDIOC_S_TUNER:
-               {
-                       struct v4l2_tuner *v = arg;
-
-                       if (v->index > 0)
-                               return -EINVAL;
+       }
+       return -EINVAL;
+}
 
-                       return 0;
-               }
-               case VIDIOC_S_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       radio->curfreq = f->frequency;
-                       if (dsbr100_setfreq(radio, radio->curfreq)==-1)
-                               warn("Set frequency failed");
-                       return 0;
-               }
-               case VIDIOC_G_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               ctrl->value = radio->muted;
+               return 0;
+       }
+       return -EINVAL;
+}
 
-                       f->type = V4L2_TUNER_RADIO;
-                       f->frequency = radio->curfreq;
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
 
-                       return 0;
-               }
-               case VIDIOC_QUERYCTRL:
-               {
-                       struct v4l2_queryctrl *qc = arg;
-                       int i;
-
-                       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-                               if (qc->id && qc->id == radio_qctrl[i].id) {
-                                       memcpy(qc, &(radio_qctrl[i]),
-                                                               sizeof(*qc));
-                                       return 0;
-                               }
-                       }
-                       return -EINVAL;
-               }
-               case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *ctrl= arg;
-
-                       switch (ctrl->id) {
-                       case V4L2_CID_AUDIO_MUTE:
-                               ctrl->value=radio->muted;
-                               return 0;
-                       }
-                       return -EINVAL;
-               }
-               case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *ctrl= arg;
-
-                       switch (ctrl->id) {
-                       case V4L2_CID_AUDIO_MUTE:
-                               if (ctrl->value) {
-                                       if (dsbr100_stop(radio)==-1)
-                                               warn("Radio did not respond properly");
-                               } else {
-                                       if (dsbr100_start(radio)==-1)
-                                               warn("Radio did not respond properly");
-                               }
-                               return 0;
-                       }
-                       return -EINVAL;
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               if (ctrl->value) {
+                       if (dsbr100_stop(radio)==-1)
+                               warn("Radio did not respond properly");
+               } else {
+                       if (dsbr100_start(radio)==-1)
+                               warn("Radio did not respond properly");
                }
-               default:
-                       return v4l_compat_translate_ioctl(inode,file,cmd,arg,
-                                                         usb_dsbr100_do_ioctl);
+               return 0;
        }
+       return -EINVAL;
 }
 
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
-                            unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
 {
-       return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
+       if (a->index > 1)
+               return -EINVAL;
+
+       strcpy(a->name, "Radio");
+       a->capability = V4L2_AUDCAP_STEREO;
+       return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+       if (i != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+                                       struct v4l2_audio *a)
+{
+       if (a->index != 0)
+               return -EINVAL;
+       return 0;
 }
 
 static int usb_dsbr100_open(struct inode *inode, struct file *file)
@@ -465,6 +430,68 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
        return 0;
 }
 
+/* File system interface */
+static const struct file_operations usb_dsbr100_fops = {
+       .owner          = THIS_MODULE,
+       .open           = usb_dsbr100_open,
+       .release        = usb_dsbr100_close,
+       .ioctl          = video_ioctl2,
+       .compat_ioctl   = v4l_compat_ioctl32,
+       .llseek         = no_llseek,
+};
+
+/* V4L2 interface */
+static struct video_device dsbr100_videodev_template =
+{
+       .owner          = THIS_MODULE,
+       .name           = "D-Link DSB-R 100",
+       .type           = VID_TYPE_TUNER,
+       .fops           = &usb_dsbr100_fops,
+       .release        = video_device_release,
+       .vidioc_querycap    = vidioc_querycap,
+       .vidioc_g_tuner     = vidioc_g_tuner,
+       .vidioc_s_tuner     = vidioc_s_tuner,
+       .vidioc_g_frequency = vidioc_g_frequency,
+       .vidioc_s_frequency = vidioc_s_frequency,
+       .vidioc_queryctrl   = vidioc_queryctrl,
+       .vidioc_g_ctrl      = vidioc_g_ctrl,
+       .vidioc_s_ctrl      = vidioc_s_ctrl,
+       .vidioc_g_audio     = vidioc_g_audio,
+       .vidioc_s_audio     = vidioc_s_audio,
+       .vidioc_g_input     = vidioc_g_input,
+       .vidioc_s_input     = vidioc_s_input,
+};
+
+/* check if the device is present and register with v4l and
+usb if it is */
+static int usb_dsbr100_probe(struct usb_interface *intf,
+                               const struct usb_device_id *id)
+{
+       struct dsbr100_device *radio;
+
+       if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
+               return -ENOMEM;
+       if (!(radio->videodev = video_device_alloc())) {
+               kfree(radio);
+               return -ENOMEM;
+       }
+       memcpy(radio->videodev, &dsbr100_videodev_template,
+               sizeof(dsbr100_videodev_template));
+       radio->removed = 0;
+       radio->users = 0;
+       radio->usbdev = interface_to_usbdev(intf);
+       radio->curfreq = FREQ_MIN*FREQ_MUL;
+       video_set_drvdata(radio->videodev, radio);
+       if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
+               warn("Could not register video device");
+               video_device_release(radio->videodev);
+               kfree(radio);
+               return -EIO;
+       }
+       usb_set_intfdata(intf, radio);
+       return 0;
+}
+
 static int __init dsbr100_init(void)
 {
        int retval = usb_register(&usb_dsbr100_driver);
index 8fbf0d8bd2783fcf1ca42238b92fc6eceae16bf0..8cf2e9df5c8aa0ae5365d2293b1e53c9c417669e 100644 (file)
 
 #define CADET_VERSION KERNEL_VERSION(0,3,3)
 
+static struct v4l2_queryctrl radio_qctrl[] = {
+       {
+               .id            = V4L2_CID_AUDIO_MUTE,
+               .name          = "Mute",
+               .minimum       = 0,
+               .maximum       = 1,
+               .default_value = 1,
+               .type          = V4L2_CTRL_TYPE_BOOLEAN,
+       },{
+               .id            = V4L2_CID_AUDIO_VOLUME,
+               .name          = "Volume",
+               .minimum       = 0,
+               .maximum       = 0xff,
+               .step          = 1,
+               .default_value = 0xff,
+               .type          = V4L2_CTRL_TYPE_INTEGER,
+       }
+};
+
 static int io=-1;              /* default to isapnp activation */
 static int radio_nr = -1;
 static int users=0;
@@ -347,135 +366,165 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 }
 
 
+static int vidioc_querycap(struct file *file, void *priv,
+                               struct v4l2_capability *v)
+{
+       v->capabilities =
+               V4L2_CAP_TUNER |
+               V4L2_CAP_READWRITE;
+       v->version = CADET_VERSION;
+       strcpy(v->driver, "ADS Cadet");
+       strcpy(v->card, "ADS Cadet");
+       return 0;
+}
 
-static int cadet_do_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
 {
-       switch(cmd)
-       {
-               case VIDIOC_QUERYCAP:
-               {
-                       struct v4l2_capability *cap = arg;
-                       memset(cap,0,sizeof(*cap));
-                       cap->capabilities =
-                               V4L2_CAP_TUNER |
-                               V4L2_CAP_READWRITE;
-                       cap->version = CADET_VERSION;
-                       strcpy(cap->driver, "ADS Cadet");
-                       strcpy(cap->card, "ADS Cadet");
-                       return 0;
+       v->type = V4L2_TUNER_RADIO;
+       switch (v->index) {
+       case 0:
+               strcpy(v->name, "FM");
+               v->capability = V4L2_TUNER_CAP_STEREO;
+               v->rangelow = 1400;     /* 87.5 MHz */
+               v->rangehigh = 1728;    /* 108.0 MHz */
+               v->rxsubchans=cadet_getstereo();
+               switch (v->rxsubchans){
+               case V4L2_TUNER_SUB_MONO:
+                       v->audmode = V4L2_TUNER_MODE_MONO;
+                       break;
+               case V4L2_TUNER_SUB_STEREO:
+                       v->audmode = V4L2_TUNER_MODE_STEREO;
+                       break;
+               default: ;
                }
-               case VIDIOC_G_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       memset(t,0,sizeof(*t));
-                       t->type = V4L2_TUNER_RADIO;
-                       switch (t->index)
-                       {
-                               case 0: strcpy(t->name, "FM");
-                                       t->capability = V4L2_TUNER_CAP_STEREO;
-                                       t->rangelow = 1400;     /* 87.5 MHz */
-                                       t->rangehigh = 1728;    /* 108.0 MHz */
-                                       t->rxsubchans=cadet_getstereo();
-                                       switch (t->rxsubchans){
-                                               case V4L2_TUNER_SUB_MONO:
-                                                       t->audmode = V4L2_TUNER_MODE_MONO;
-                                                       break;
-                                               case V4L2_TUNER_SUB_STEREO:
-                                                       t->audmode = V4L2_TUNER_MODE_STEREO;
-                                                       break;
-                                               default: ;
-                                       }
-                                       break;
-                               case 1: strcpy(t->name, "AM");
-                                       t->capability = V4L2_TUNER_CAP_LOW;
-                                       t->rangelow = 8320;      /* 520 kHz */
-                                       t->rangehigh = 26400;    /* 1650 kHz */
-                                       t->rxsubchans = V4L2_TUNER_SUB_MONO;
-                                       t->audmode = V4L2_TUNER_MODE_MONO;
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
+               break;
+       case 1:
+               strcpy(v->name, "AM");
+               v->capability = V4L2_TUNER_CAP_LOW;
+               v->rangelow = 8320;      /* 520 kHz */
+               v->rangehigh = 26400;    /* 1650 kHz */
+               v->rxsubchans = V4L2_TUNER_SUB_MONO;
+               v->audmode = V4L2_TUNER_MODE_MONO;
+               break;
+       default:
+               return -EINVAL;
+       }
+       v->signal = sigstrength; /* We might need to modify scaling of this */
+       return 0;
+}
 
-                       t->signal = sigstrength; /* We might need to modify scaling of this */
-                       return 0;
-               }
-               case VIDIOC_S_TUNER:
-               {
-                       struct v4l2_tuner *t = arg;
-                       if((t->index != 0)&&(t->index != 1))
-                               return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *v)
+{
+       if((v->index != 0)&&(v->index != 1))
+               return -EINVAL;
+       curtuner = v->index;
+       return 0;
+}
 
-                       curtuner = t->index;
-                       return 0;
-               }
-               case VIDIOC_G_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
-                       memset(f,0,sizeof(*f));
-                       f->tuner = curtuner;
-                       f->type = V4L2_TUNER_RADIO;
-                       f->frequency = cadet_getfreq();
-                       return 0;
-               }
-               case VIDIOC_S_FREQUENCY:
-               {
-                       struct v4l2_frequency *f = arg;
-                       if (f->type != V4L2_TUNER_RADIO){
-                               return -EINVAL;
-                       }
-                       if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) {
-                               return -EINVAL;
-                       }
-                       if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) {
-                               return -EINVAL;
-                       }
-                       cadet_setfreq(f->frequency);
-                       return 0;
-               }
-               case VIDIOC_G_CTRL:
-               {
-                       struct v4l2_control *c = arg;
-                       switch (c->id){
-                               case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
-                                       c->value = (cadet_getvol() == 0);
-                                       break;
-                               case V4L2_CID_AUDIO_VOLUME:
-                                       c->value = cadet_getvol();
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
-                       return 0;
-               }
-               case VIDIOC_S_CTRL:
-               {
-                       struct v4l2_control *c = arg;
-                       switch (c->id){
-                               case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
-                                       if (c->value) cadet_setvol(0);
-                                               else cadet_setvol(0xffff);
-                                       break;
-                               case V4L2_CID_AUDIO_VOLUME:
-                                       cadet_setvol(c->value);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
+static int vidioc_g_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       f->tuner = curtuner;
+       f->type = V4L2_TUNER_RADIO;
+       f->frequency = cadet_getfreq();
+       return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       if (f->type != V4L2_TUNER_RADIO)
+               return -EINVAL;
+       if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+               return -EINVAL;
+       if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+               return -EINVAL;
+       cadet_setfreq(f->frequency);
+       return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+                               struct v4l2_queryctrl *qc)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+               if (qc->id && qc->id == radio_qctrl[i].id) {
+                       memcpy(qc, &(radio_qctrl[i]),
+                                               sizeof(*qc));
                        return 0;
                }
+       }
+       return -EINVAL;
+}
 
-               default:
-                       return -ENOIOCTLCMD;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
+{
+       switch (ctrl->id){
+       case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+               ctrl->value = (cadet_getvol() == 0);
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+               ctrl->value = cadet_getvol();
+               break;
+       default:
+               return -EINVAL;
        }
+       return 0;
 }
 
-static int
-cadet_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                               struct v4l2_control *ctrl)
 {
-       return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
+       switch (ctrl->id){
+       case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+               if (ctrl->value)
+                       cadet_setvol(0);
+               else
+                       cadet_setvol(0xffff);
+               break;
+       case V4L2_CID_AUDIO_VOLUME:
+               cadet_setvol(ctrl->value);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
+{
+       if (a->index > 1)
+               return -EINVAL;
+       strcpy(a->name, "Radio");
+       a->capability = V4L2_AUDCAP_STEREO;
+       return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+       *i = 0;
+       return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+       if (i != 0)
+               return -EINVAL;
+       return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+                               struct v4l2_audio *a)
+{
+       if (a->index != 0)
+               return -EINVAL;
+       return 0;
 }
 
 static int
@@ -512,7 +561,7 @@ static const struct file_operations cadet_fops = {
        .open           = cadet_open,
        .release        = cadet_release,
        .read           = cadet_read,
-       .ioctl          = cadet_ioctl,
+       .ioctl          = video_ioctl2,
        .poll           = cadet_poll,
        .compat_ioctl   = v4l_compat_ioctl32,
        .llseek         = no_llseek,
@@ -524,6 +573,18 @@ static struct video_device cadet_radio=
        .name           = "Cadet radio",
        .type           = VID_TYPE_TUNER,
        .fops           = &cadet_fops,
+       .vidioc_querycap    = vidioc_querycap,
+       .vidioc_g_tuner     = vidioc_g_tuner,
+       .vidioc_s_tuner     = vidioc_s_tuner,
+       .vidioc_g_frequency = vidioc_g_frequency,
+       .vidioc_s_frequency = vidioc_s_frequency,
+       .vidioc_queryctrl   = vidioc_queryctrl,
+       .vidioc_g_ctrl      = vidioc_g_ctrl,
+       .vidioc_s_ctrl      = vidioc_s_ctrl,
+       .vidioc_g_audio     = vidioc_g_audio,
+       .vidioc_s_audio     = vidioc_s_audio,
+       .vidioc_g_input     = vidioc_g_input,
+       .vidioc_s_input     = vidioc_s_input,
 };
 
 static struct pnp_device_id cadet_pnp_devices[] = {
index 11f80cacd6edef44f0f224a768962a288f63cfa2..8e33a19a22a3134c16109d60ebd5bff971ec6056 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/mutex.h>
 #include <linux/pci.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
@@ -110,7 +109,6 @@ struct radio_device {
                muted,  /* VIDEO_AUDIO_MUTE */
                stereo, /* VIDEO_TUNER_STEREO_ON */
                tuned;  /* signal strength (0 or 0xffff) */
-       struct mutex lock;
 };
 
 static u32 radio_bits_get(struct radio_device *dev)
@@ -394,7 +392,6 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
        }
 
        radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-       mutex_init(&radio_unit->lock);
 
        maestro_radio_inst = video_device_alloc();
        if (maestro_radio_inst == NULL) {
index a4715901512d48cf4c93ba5aa477d4536e6e0f24..203f4373eeb8f7ea189cd3ef2705a1ba9c7f55c2 100644 (file)
@@ -410,7 +410,6 @@ static struct video_device zoltrix_radio =
        .owner          = THIS_MODULE,
        .name           = "Zoltrix Radio Plus",
        .type           = VID_TYPE_TUNER,
-       .hardware       = 0,
        .fops           = &zoltrix_fops,
        .vidioc_querycap    = vidioc_querycap,
        .vidioc_g_tuner     = vidioc_g_tuner,
index bc773781993a5b75113388a623f12f64fa697556..5cb3f54b548b1dc9f678d486cafa5b8026c58135 100644 (file)
@@ -2,14 +2,19 @@
 # Multimedia Video device configuration
 #
 
-menu "Video Capture Adapters"
+menuconfig VIDEO_CAPTURE_DRIVERS
+       bool "Video capture adapters"
        depends on VIDEO_DEV
+       default y
+       ---help---
+         Say Y here to enable selecting the video adapters for
+         webcams, analog TV, and hybrid analog/digital TV.
+         Some of those devices also supports FM radio.
 
-comment "Video Capture Adapters"
+if VIDEO_CAPTURE_DRIVERS
 
 config VIDEO_ADV_DEBUG
        bool "Enable advanced debug functionality"
-       depends on VIDEO_DEV
        default n
        ---help---
          Say Y here to enable advanced debugging functionality on some
@@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO
 #
 
 menu "Encoders/decoders and other helper chips"
-       depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+       depends on !VIDEO_HELPER_CHIPS_AUTO
 
 comment "Audio decoders"
 
@@ -61,7 +66,7 @@ config VIDEO_TDA7432
 
 config VIDEO_TDA9840
        tristate "Philips TDA9840 audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tda9840 audio decoder chip found on some Zoran boards.
 
@@ -79,7 +84,7 @@ config VIDEO_TDA9875
 
 config VIDEO_TEA6415C
        tristate "Philips TEA6415C audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tea6415c audio decoder chip found on some bt8xx boards.
 
@@ -88,7 +93,7 @@ config VIDEO_TEA6415C
 
 config VIDEO_TEA6420
        tristate "Philips TEA6420 audio processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C
        ---help---
          Support for tea6420 audio decoder chip found on some bt8xx boards.
 
@@ -469,7 +474,7 @@ config VIDEO_SAA5246A
 
 config VIDEO_SAA5249
        tristate "SAA5249 Teletext processor"
-       depends on VIDEO_DEV && I2C && VIDEO_V4L2
+       depends on I2C && VIDEO_V4L2
        help
          Support for I2C bus based teletext using the SAA5249 chip. At the
          moment this is only useful on some European WinTV cards.
@@ -479,7 +484,7 @@ config VIDEO_SAA5249
 
 config TUNER_3036
        tristate "SAB3036 tuner"
-       depends on VIDEO_DEV && I2C && VIDEO_V4L1
+       depends on I2C && VIDEO_V4L1
        help
          Say Y here to include support for Philips SAB3036 compatible tuners.
          If in doubt, say N.
@@ -681,8 +686,12 @@ config VIDEO_CAFE_CCIC
 # USB Multimedia device configuration
 #
 
-menu "V4L USB devices"
-       depends on USB && VIDEO_DEV
+menuconfig V4L_USB_DRIVERS
+       bool "V4L USB devices"
+       depends on USB
+       default y
+
+if V4L_USB_DRIVERS
 
 source "drivers/media/video/pvrusb2/Kconfig"
 
@@ -707,7 +716,7 @@ config VIDEO_OVCAMCHIP
 
 config USB_W9968CF
        tristate "USB W996[87]CF JPEG Dual Mode Camera support"
-       depends on USB && VIDEO_V4L1 && I2C
+       depends on VIDEO_V4L1 && I2C
        select VIDEO_OVCAMCHIP
        ---help---
          Say Y here if you want support for cameras based on OV681 or
@@ -725,7 +734,7 @@ config USB_W9968CF
 
 config USB_OV511
        tristate "USB OV511 Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -736,7 +745,7 @@ config USB_OV511
 
 config USB_SE401
        tristate "USB SE401 Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -749,7 +758,7 @@ source "drivers/media/video/sn9c102/Kconfig"
 
 config USB_STV680
        tristate "USB STV680 (Pencam) Camera support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. This includes the Pencam line of cameras.
@@ -765,7 +774,7 @@ source "drivers/media/video/pwc/Kconfig"
 
 config USB_ZR364XX
        tristate "USB ZR364XX Camera support"
-       depends on USB && VIDEO_V4L2
+       depends on VIDEO_V4L2
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port.
@@ -775,6 +784,6 @@ config USB_ZR364XX
          To compile this driver as a module, choose M here: the
          module will be called zr364xx.
 
-endmenu # V4L USB devices
+endif # V4L_USB_DRIVERS
 
-endmenu
+endif # VIDEO_CAPTURE_DRIVERS
index 1757a588970fc242717128f707765029a9862eac..67bda9f9a44bfa48998de9f3566ef57da7222ded 100644 (file)
@@ -555,7 +555,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
 {
        struct v4l2_pix_format *pix;
        int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
-       int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+       int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
 
        switch (fmt->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -567,7 +567,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
                Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
                Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
 
-               Vlines = pix->height + (is_pal ? 4 : 7);
+               Vlines = pix->height + (is_50Hz ? 4 : 7);
 
                if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
                    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
index 2ebde2fdbcbe8b7cb3c95fd51ad3393ecf01c70c..543b05ebc0e79ba74851f2a7c4b4180bde2d1e93 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
 #include <asm/delay.h>
 
 #include "cx88.h"
@@ -612,7 +613,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
 }
 
 /* Driver asked for hardware access. */
-int cx8802_request_acquire(struct cx8802_driver *drv)
+static int cx8802_request_acquire(struct cx8802_driver *drv)
 {
        struct cx88_core *core = drv->core;
 
@@ -632,7 +633,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv)
 }
 
 /* Driver asked to release hardware. */
-int cx8802_request_release(struct cx8802_driver *drv)
+static int cx8802_request_release(struct cx8802_driver *drv)
 {
        struct cx88_core *core = drv->core;
 
index b94ef8ab28c1503f4602565bb7b3c24356614734..98fa35421bdd4d3da05be0b0ad6bdfdcbb9804f5 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/dma-mapping.h>
 #include <asm/div64.h>
 
 #include "cx88.h"
index 6068c9bf82cd45da8f7d78aa06bdc2a5120dae1d..82bc3a28aa22941ad7aa0617ece154c910e17880 100644 (file)
@@ -111,10 +111,6 @@ static struct i2c_adapter vp3054_i2c_adap_template = {
        .id                = I2C_HW_B_CX2388x,
 };
 
-static struct i2c_client vp3054_i2c_client_template = {
-       .name   = "VP-3054",
-};
-
 int vp3054_i2c_probe(struct cx8802_dev *dev)
 {
        struct cx88_core *core = dev->core;
@@ -133,8 +129,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
               sizeof(vp3054_i2c->adap));
        memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
               sizeof(vp3054_i2c->algo));
-       memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
-              sizeof(vp3054_i2c->client));
 
        vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
 
@@ -144,7 +138,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        vp3054_i2c->algo.data = dev;
        i2c_set_adapdata(&vp3054_i2c->adap, dev);
        vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
-       vp3054_i2c->client.adapter = &vp3054_i2c->adap;
 
        vp3054_bit_setscl(dev,1);
        vp3054_bit_setsda(dev,1);
index b7a0a04d2423e4034d7c35a6de9f0712f13aca6d..637a7d2322389c79ac161981e1ce6fcd9b7ebf7c 100644 (file)
@@ -26,7 +26,6 @@
 struct vp3054_i2c_state {
        struct i2c_adapter         adap;
        struct i2c_algo_bit_data   algo;
-       struct i2c_client          client;
        u32                        state;
 };
 
index 9285a58e47aae9a166723809b1df65c57f1525a4..3823b62da4a4b70f3f28b5b4298ae65c8cd4fdb2 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_EM28XX
        tristate "Empia EM2800/2820/2840 USB video capture support"
-       depends on VIDEO_V4L1 && USB && I2C
+       depends on VIDEO_V4L1 && I2C
        select VIDEO_BUF
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index c6bff705688d0e02404b7730a972557042e67cd4..664676f440685cdc0f405ba97a84560e5f132811 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ET61X251
        tristate "USB ET61X[12]51 PC Camera Controller support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on Etoms ET61X151
          or ET61X251 PC Camera Controllers.
index 45b9328a538f5c8d4809462c4147a23c1f217df7..e29f949adf57d255a67b9967dc90d6ce01fa22e9 100644 (file)
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
 struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
 
 /* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
 
 /* add your revision and whatnot here */
 static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
index 1637097ddec742c68ddbf2d17be485855c2b4be8..8976487a65f3c7994481a7657616b9acfaf75952 100644 (file)
@@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
        struct ivtv_open_id *item;
        struct ivtv *itv = NULL;
        struct ivtv_stream *s = NULL;
-       int minor = MINOR(inode->i_rdev);
+       int minor = iminor(inode);
 
        /* Find which card this open was on */
        spin_lock(&ivtv_cards_lock);
index 5645c9318890d6c701f3bfb9aed7729830fa42fb..d0c2cd7854303fc8167a8203f85ee7f30493a27b 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_PVRUSB2
        tristate "Hauppauge WinTV-PVR USB2 support"
-       depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
        select FW_LOADER
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index 5669c8ca9ca3b5a60e49e1b47b07b99455dbb04a..20b614436d2cffc16b239025ec79736dda9ddab1 100644 (file)
@@ -391,22 +391,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
 int pvr2_encoder_configure(struct pvr2_hdw *hdw)
 {
        int ret;
+       int val;
        pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
                   " (cx2341x module)");
        hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
        hdw->enc_ctl_state.width = hdw->res_hor_val;
        hdw->enc_ctl_state.height = hdw->res_ver_val;
-       hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
-                                      (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+       hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
                                      0 : 1);
 
        ret = 0;
 
        ret |= pvr2_encoder_prep_config(hdw);
 
+       /* saa7115: 0xf0 */
+       val = 0xf0;
+       if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+               /* ivtv cx25840: 0x140 */
+               val = 0x140;
+       }
+
        if (!ret) ret = pvr2_encoder_vcmd(
                hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
-               0xf0, 0xf0);
+               val, val);
 
        /* setup firmware to notify us about some events (don't know why...) */
        if (!ret) ret = pvr2_encoder_vcmd(
index acf651e01f94aeebff01dd7e82c1a19832a75b09..1311891e7ee3dd0d85acc751c0ad40362271e3c4 100644 (file)
@@ -83,7 +83,7 @@ static struct pvr2_string_table pvr2_client_lists[] = {
 };
 
 static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DECLARE_MUTEX(pvr2_unit_sem);
+static DEFINE_MUTEX(pvr2_unit_mtx);
 
 static int ctlchg = 0;
 static int initusbreset = 1;
@@ -2076,14 +2076,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
        hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
        if (!hdw->ctl_read_urb) goto fail;
 
-       down(&pvr2_unit_sem); do {
+       mutex_lock(&pvr2_unit_mtx); do {
                for (idx = 0; idx < PVR_NUM; idx++) {
                        if (unit_pointers[idx]) continue;
                        hdw->unit_number = idx;
                        unit_pointers[idx] = hdw;
                        break;
                }
-       } while (0); up(&pvr2_unit_sem);
+       } while (0); mutex_unlock(&pvr2_unit_mtx);
 
        cnt1 = 0;
        cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
@@ -2186,13 +2186,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
        }
        pvr2_i2c_core_done(hdw);
        pvr2_hdw_remove_usb_stuff(hdw);
-       down(&pvr2_unit_sem); do {
+       mutex_lock(&pvr2_unit_mtx); do {
                if ((hdw->unit_number >= 0) &&
                    (hdw->unit_number < PVR_NUM) &&
                    (unit_pointers[hdw->unit_number] == hdw)) {
                        unit_pointers[hdw->unit_number] = NULL;
                }
-       } while (0); up(&pvr2_unit_sem);
+       } while (0); mutex_unlock(&pvr2_unit_mtx);
        kfree(hdw->controls);
        kfree(hdw->mpeg_ctrl_info);
        kfree(hdw->std_defs);
index 58fc3c730fe189bb5f608f42a04a9316fd10be41..6786d3c0c98beaf8b1a3fc84d55787f97a7f5d89 100644 (file)
@@ -23,6 +23,7 @@
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-debug.h"
 #include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2.h"
 
 #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
 
@@ -38,6 +39,10 @@ static unsigned int i2c_scan = 0;
 module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
 
+static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
+module_param_array(ir_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+
 static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
                                             unsigned int detail,
                                             char *buf,unsigned int maxlen);
@@ -273,6 +278,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
        return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
 }
 
+/* This is an entry point designed to always fail any attempt to perform a
+   transfer.  We use this to cause certain I2C addresses to not be
+   probed. */
+static int i2c_black_hole(struct pvr2_hdw *hdw,
+                          u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+       return -EIO;
+}
+
 /* This is a special entry point that is entered if an I2C operation is
    attempted to a cx25840 chip on model 24xxx hardware.  This chip can
    sometimes wedge itself.  Worse still, when this happens msp3400 can
@@ -994,10 +1008,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
        }
 
        /* However, deal with various special cases for 24xxx hardware. */
+       if (ir_mode[hdw->unit_number] == 0) {
+               printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+               hdw->i2c_func[0x18] = i2c_black_hole;
+       } else if (ir_mode[hdw->unit_number] == 1) {
+               if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+                       hdw->i2c_func[0x18] = i2c_24xxx_ir;
+               }
+       }
        if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
                hdw->i2c_func[0x1b] = i2c_hack_wm8775;
                hdw->i2c_func[0x44] = i2c_hack_cx25840;
-               hdw->i2c_func[0x18] = i2c_24xxx_ir;
        }
 
        // Configure the adapter and set up everything else related to it.
index a741c556a39a06119619f0ff7cea0fd7127d71ad..7ab79baa1c8ce43aa771e21001b83e24006d25e5 100644 (file)
@@ -518,40 +518,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
        }
        sfp->item_last = cip;
 
-       cip->attr_name.attr.owner = THIS_MODULE;
        cip->attr_name.attr.name = "name";
        cip->attr_name.attr.mode = S_IRUGO;
        cip->attr_name.show = fp->show_name;
 
-       cip->attr_type.attr.owner = THIS_MODULE;
        cip->attr_type.attr.name = "type";
        cip->attr_type.attr.mode = S_IRUGO;
        cip->attr_type.show = fp->show_type;
 
-       cip->attr_min.attr.owner = THIS_MODULE;
        cip->attr_min.attr.name = "min_val";
        cip->attr_min.attr.mode = S_IRUGO;
        cip->attr_min.show = fp->show_min;
 
-       cip->attr_max.attr.owner = THIS_MODULE;
        cip->attr_max.attr.name = "max_val";
        cip->attr_max.attr.mode = S_IRUGO;
        cip->attr_max.show = fp->show_max;
 
-       cip->attr_val.attr.owner = THIS_MODULE;
        cip->attr_val.attr.name = "cur_val";
        cip->attr_val.attr.mode = S_IRUGO;
 
-       cip->attr_custom.attr.owner = THIS_MODULE;
        cip->attr_custom.attr.name = "custom_val";
        cip->attr_custom.attr.mode = S_IRUGO;
 
-       cip->attr_enum.attr.owner = THIS_MODULE;
        cip->attr_enum.attr.name = "enum_val";
        cip->attr_enum.attr.mode = S_IRUGO;
        cip->attr_enum.show = fp->show_enum;
 
-       cip->attr_bits.attr.owner = THIS_MODULE;
        cip->attr_bits.attr.name = "bit_val";
        cip->attr_bits.attr.mode = S_IRUGO;
        cip->attr_bits.show = fp->show_bits;
@@ -616,12 +608,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
 
        dip = kzalloc(sizeof(*dip),GFP_KERNEL);
        if (!dip) return;
-       dip->attr_debugcmd.attr.owner = THIS_MODULE;
        dip->attr_debugcmd.attr.name = "debugcmd";
        dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
        dip->attr_debugcmd.show = debugcmd_show;
        dip->attr_debugcmd.store = debugcmd_store;
-       dip->attr_debuginfo.attr.owner = THIS_MODULE;
        dip->attr_debuginfo.attr.name = "debuginfo";
        dip->attr_debuginfo.attr.mode = S_IRUGO;
        dip->attr_debuginfo.show = debuginfo_show;
@@ -811,7 +801,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                return;
        }
 
-       sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
        sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
        sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -825,7 +814,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_minor_number_created_ok = !0;
        }
 
-       sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE;
        sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
        sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -839,7 +827,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->v4l_radio_minor_number_created_ok = !0;
        }
 
-       sfp->attr_unit_number.attr.owner = THIS_MODULE;
        sfp->attr_unit_number.attr.name = "unit_number";
        sfp->attr_unit_number.attr.mode = S_IRUGO;
        sfp->attr_unit_number.show = unit_number_show;
@@ -852,7 +839,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                sfp->unit_number_created_ok = !0;
        }
 
-       sfp->attr_bus_info.attr.owner = THIS_MODULE;
        sfp->attr_bus_info.attr.name = "bus_info_str";
        sfp->attr_bus_info.attr.mode = S_IRUGO;
        sfp->attr_bus_info.show = bus_info_show;
index 8fdf7101d3bfcabb31863d6f0a5622ed5071bb5e..7298cf2e1650f53f2c5e90f0873045d295e43c17 100644 (file)
@@ -1,6 +1,6 @@
 config USB_PWC
        tristate "USB Philips Cameras"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y or M here if you want to use one of these Philips & OEM
          webcams:
index 4ea479baee7448c18f407c138a00698851344d9d..50f15adfa7c87ff0a77a2d0284e8826aa8c54265 100644 (file)
@@ -1170,6 +1170,42 @@ struct saa7134_board saa7134_boards[] = {
                        .amux   = LINE2,
                },
        },
+    [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
+               /* Barry Scott <barry.scott@onelan.co.uk> */
+               .name           = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
+               .audio_clock    = 0x187de7,
+               .tuner_type     = TUNER_PHILIPS_PAL_I,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .inputs         = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               },{
+                       .name   = name_tv_mono,
+                       .vmux   = 1,
+                       .amux   = LINE2,
+                       .tv     = 1,
+               },{
+                       .name   = name_comp1,
+                       .vmux   = 3,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
+               },{
+                       .name   = "CVid over SVid",
+                       .vmux   = 0,
+                       .amux   = LINE1,
+               }},
+               .radio = {
+                       .name   = name_radio,
+                       .amux   = LINE2,
+               },
+       },
        [SAA7134_BOARD_AVACSSMARTTV] = {
                /* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
                .name           = "AVACS SmartTV",
@@ -2754,6 +2790,35 @@ struct saa7134_board saa7134_boards[] = {
                        .amux   = LINE1,
                },
        },
+       [SAA7134_BOARD_KWORLD_DVBT_210] = {
+               .name           = "KWorld DVB-T 210",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .gpiomask       = 1 << 21,
+               .inputs = {{
+                       .name   = name_tv,
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               },{
+                       .name   = name_comp1,
+                       .vmux   = 3,
+                       .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
+               }},
+               .radio = {
+                       .name   = name_radio,
+                       .amux   = TV,
+                       .gpio   = 0x0200000,
+               },
+       },
        [SAA7134_BOARD_KWORLD_ATSC110] = {
                .name           = "Kworld ATSC110",
                .audio_clock    = 0x00187de7,
@@ -3407,6 +3472,36 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0200000,
                },
        },
+       [SAA7134_BOARD_SABRENT_TV_PCB05] = {
+               .name           = "Sabrent PCMCIA TV-PCB05",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .inputs         = {{
+                       .name = name_tv,
+                       .vmux = 1,
+                       .amux = TV,
+                       .tv   = 1,
+               },{
+                       .name = name_comp1,
+                       .vmux = 3,
+                       .amux = LINE1,
+               },{
+                       .name = name_comp2,
+                       .vmux = 0,
+                       .amux = LINE1,
+               },{
+                       .name = name_svideo,
+                       .vmux = 8,
+                       .amux = LINE1,
+               }},
+               .mute = {
+                       .name = name_mute,
+                       .amux = TV,
+               },
+       },
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3515,7 +3610,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x5168, /* Animation Technologies (LifeView) */
-               .subdevice    = 0x0214, /* Standard PCI, LR214WF */
+               .subdevice    = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
+               .driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x5168, /* Animation Technologies (LifeView) */
+               .subdevice    = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
                .driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -3687,6 +3788,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x1019,
                .subdevice    = 0x4cb5,
                .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x1019,
+               .subdevice    = 0x4cb6,
+               .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB6,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3913,6 +4020,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x17de,
                .subdevice    = 0x7201,
                .driver_data  = SAA7134_BOARD_TEVION_DVBT_220RF,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x17de,
+               .subdevice    = 0x7250,
+               .driver_data  = SAA7134_BOARD_KWORLD_DVBT_210,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
@@ -4099,6 +4212,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x1043,
                .subdevice    = 0x4857,
                .driver_data  = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+               .subvendor    = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
+               .subdevice    = 0x2003, /* OEM cardbus */
+               .driver_data  = SAA7134_BOARD_SABRENT_TV_PCB05,
        },{
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -4178,6 +4297,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
        case SAA7134_BOARD_CINERGY600_MK3:
        case SAA7134_BOARD_ECS_TVP3XP:
        case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+       case SAA7134_BOARD_ECS_TVP3XP_4CB6:
        case SAA7134_BOARD_MD2819:
        case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
        case SAA7134_BOARD_KWORLD_XPERT:
@@ -4426,6 +4546,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_PINNACLE_PCTV_310i:
+       case SAA7134_BOARD_KWORLD_DVBT_210:
        case SAA7134_BOARD_TEVION_DVBT_220RF:
        case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
        case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
index 65aec881bbde9a4e6f5dd622b3032a34963f9c15..e0eec80088c7e3060efc95f983d66530b0b709de 100644 (file)
@@ -887,6 +887,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
        .antenna_switch= 2,
        .request_firmware = philips_tda1004x_request_firmware
 };
+static struct tda1004x_config kworld_dvb_t_210_config = {
+       .demod_address = 0x08,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X,
+       .gpio_config   = TDA10046_GP11_I,
+       .if_freq       = TDA10046_FREQ_045,
+       .i2c_gate      = 0x4b,
+       .tuner_address = 0x61,
+       .tuner_config  = 2,
+       .antenna_switch= 1,
+       .request_firmware = philips_tda1004x_request_firmware
+};
 /* ------------------------------------------------------------------
  * special case: this card uses saa713x GPIO22 for the mode switch
  */
@@ -1039,6 +1053,9 @@ static int dvb_init(struct saa7134_dev *dev)
                        dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
                }
                break;
+       case SAA7134_BOARD_KWORLD_DVBT_210:
+               configure_tda827x_fe(dev, &kworld_dvb_t_210_config);
+               break;
        case SAA7134_BOARD_PHILIPS_TIGER:
                configure_tda827x_fe(dev, &philips_tiger_config);
                break;
index 62224cc958f1077c5efe6fe491308d7acfd18933..15623b27ad2e0f92ff16434e70a1050c81648c0d 100644 (file)
@@ -235,6 +235,9 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_M102      110
 #define SAA7134_BOARD_ASUS_P7131_4871     111
 #define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
+#define SAA7134_BOARD_ECS_TVP3XP_4CB6  113
+#define SAA7134_BOARD_KWORLD_DVBT_210 114
+#define SAA7134_BOARD_SABRENT_TV_PCB05     115
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
index 19204f5686e16759991a9bb77eb528f6de136c3e..f71f272776dedca9d945ad7b6d4fe760d53767bc 100644 (file)
@@ -1,6 +1,6 @@
 config USB_SN9C102
        tristate "USB SN9C1xx PC Camera Controller support"
-       depends on USB && VIDEO_V4L2
+       depends on VIDEO_V4L2
        ---help---
          Say Y here if you want support for cameras based on SONiX SN9C101,
          SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
index 680e74634527ce345ecdb6759cf218b211c17db1..11fcb49f5b99180b34de68f522f1090ca96fa07a 100644 (file)
@@ -141,7 +141,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
 
 void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor)
+                     const struct sn9c102_sensor* sensor)
 {
        memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
 }
index 89f83354de3be0cbd094fc282fd98cd007244bdd..74a204f8ebc870c254f7b0a850bf9ab5699ede9d 100644 (file)
@@ -48,8 +48,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004-2007 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.39"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 39)
+#define SN9C102_MODULE_VERSION  "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 1, 44)
 
 /*****************************************************************************/
 
@@ -209,38 +209,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
 }
 
 /*****************************************************************************/
+
 /*
- * Write a sequence of count value/register pairs.  Returns -1 after the
* first failed write, or 0 for no errors.
- */
+   Write a sequence of count value/register pairs. Returns -1 after the first
  failed write, or 0 for no errors.
+*/
 int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
                       int count)
 {
        struct usb_device* udev = cam->usbdev;
-       u8* value = cam->control_buffer;  /* Needed for DMA'able memory */
+       u8* buff = cam->control_buffer;
        int i, res;
 
        for (i = 0; i < count; i++) {
                u8 index = valreg[i][1];
 
                /*
-                * index is a u8, so it must be <256 and can't be out of range.
-                * If we put in a check anyway, gcc annoys us with a warning
-                * that our check is useless.  People get all uppity when they
-                * see warnings in the kernel compile.
-                */
-
-               *value = valreg[i][0];
-               res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-                                     0x08, 0x41, index, 0,
-                                     value, 1, SN9C102_CTRL_TIMEOUT);
+                  index is a u8, so it must be <256 and can't be out of range.
+                  If we put in a check anyway, gcc annoys us with a warning
+                  hat our check is useless. People get all uppity when they
+                  see warnings in the kernel compile.
+               */
+
+               *buff = valreg[i][0];
+
+               res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+                                     0x41, index, 0, buff, 1,
+                                     SN9C102_CTRL_TIMEOUT);
+
                if (res < 0) {
                        DBG(3, "Failed to write a register (value 0x%02X, "
-                              "index 0x%02X, error %d)", *value, index, res);
+                              "index 0x%02X, error %d)", *buff, index, res);
                        return -1;
                }
 
-               cam->reg[index] = *value;
+               cam->reg[index] = *buff;
        }
 
        return 0;
@@ -272,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
 }
 
 
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
 {
        struct usb_device* udev = cam->usbdev;
        u8* buff = cam->control_buffer;
@@ -299,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
 
 
 static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+                const struct sn9c102_sensor* sensor)
 {
        int i, r;
 
@@ -320,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
 
 static int
 sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
-                             struct sn9c102_sensor* sensor)
+                             const struct sn9c102_sensor* sensor)
 {
        int r , err = 0;
 
@@ -342,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
 
 static int
 sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
-                              struct sn9c102_sensor* sensor)
+                              const struct sn9c102_sensor* sensor)
 {
        int r;
        r = sn9c102_read_reg(cam, 0x08);
@@ -352,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-                        struct sn9c102_sensor* sensor, u8 data0, u8 data1,
-                        u8 n, u8 buffer[])
+                        const struct sn9c102_sensor* sensor, u8 data0,
+                        u8 data1, u8 n, u8 buffer[])
 {
        struct usb_device* udev = cam->usbdev;
        u8* data = cam->control_buffer;
-       int err = 0, res;
+       int i = 0, err = 0, res;
 
        /* Write cycle */
        data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -402,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
        }
 
        if (buffer)
-               memcpy(buffer, data, sizeof(buffer));
+               for (i = 0; i < n && i < 5; i++)
+                       buffer[n-i-1] = data[4-i];
 
        return (int)data[4];
 }
@@ -410,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-                         struct sn9c102_sensor* sensor, u8 n, u8 data0,
+                         const struct sn9c102_sensor* sensor, u8 n, u8 data0,
                          u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
 {
        struct usb_device* udev = cam->usbdev;
@@ -449,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_read(struct sn9c102_device* cam,
-                    struct sn9c102_sensor* sensor, u8 address)
+                    const struct sn9c102_sensor* sensor, u8 address)
 {
        return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
                                        address, 1, NULL);
@@ -458,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
 
 int
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor, u8 address, u8 value)
+                     const struct sn9c102_sensor* sensor, u8 address, u8 value)
 {
        return sn9c102_i2c_try_raw_write(cam, sensor, 3,
                                         sensor->i2c_slave_id, address,
@@ -657,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
 }
 
 
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
-       static const u8 eoi_marker[2] = {0xff, 0xd9};
-
-       memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
-       f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
 static void sn9c102_urb_complete(struct urb *urb)
 {
        struct sn9c102_device* cam = urb->context;
@@ -3181,14 +3176,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
 
 static const struct file_operations sn9c102_fops = {
        .owner = THIS_MODULE,
-       .open =    sn9c102_open,
+       .open = sn9c102_open,
        .release = sn9c102_release,
-       .ioctl =   sn9c102_ioctl,
+       .ioctl = sn9c102_ioctl,
        .compat_ioctl = v4l_compat_ioctl32,
-       .read =    sn9c102_read,
-       .poll =    sn9c102_poll,
-       .mmap =    sn9c102_mmap,
-       .llseek =  no_llseek,
+       .read = sn9c102_read,
+       .poll = sn9c102_poll,
+       .mmap = sn9c102_mmap,
+       .llseek = no_llseek,
 };
 
 /*****************************************************************************/
@@ -3251,7 +3246,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                break;
        }
 
-       for  (i = 0; sn9c102_sensor_table[i]; i++) {
+       for  (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
                err = sn9c102_sensor_table[i](cam);
                if (!err)
                        break;
@@ -3262,7 +3257,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                DBG(3, "Support for %s maintained by %s",
                    cam->sensor.name, cam->sensor.maintainer);
        } else {
-               DBG(1, "No supported image sensor detected");
+               DBG(1, "No supported image sensor detected for this bridge");
                err = -ENODEV;
                goto fail;
        }
index f49bd8c5b86ec8e78b176e27766e8d8c1a7f2d03..916054faf9be46d62e083a4ffb670c40d32b582c 100644 (file)
@@ -86,6 +86,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
        { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
        /* SN9C105 */
+       { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+       { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -100,6 +102,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
        { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
        { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
        /* SN9C120 */
+       { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
        { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
@@ -148,7 +151,6 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
        &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
        &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
        &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-       NULL,
 };
 
 #endif /* _SN9C102_DEVTABLE_H_ */
index 28a861aed044a2eb9ad5a3871b22c501b6eafb0b..eaf9ad0dc8a65596a8b5836a161a4d334d34fa87 100644 (file)
@@ -144,7 +144,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
        .name = "HV7131D",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -248,12 +248,10 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
 
        err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
                                       {0x28, 0x17});
-       if (err)
-               return -EIO;
 
        r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
        r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
-       if (r0 < 0 || r1 < 0)
+       if (err || r0 < 0 || r1 < 0)
                return -EIO;
 
        if (r0 != 0x00 || r1 != 0x04)
index 5a495baa5f95d6e35c340ba6506546f7fc00b7dd..0fc401223cfc9c08741fa3595b93cadf7811f5b3 100644 (file)
@@ -44,7 +44,6 @@ static int hv7131r_init(struct sn9c102_device* cam)
                                               {0xb0, 0x2b}, {0xc0, 0x2c},
                                               {0xd0, 0x2d}, {0xe0, 0x2e},
                                               {0xf0, 0x2f}, {0xff, 0x30});
-
                break;
        case BRIDGE_SN9C105:
        case BRIDGE_SN9C120:
@@ -254,7 +253,7 @@ static int hv7131r_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor hv7131r = {
+static const struct sn9c102_sensor hv7131r = {
        .name = "HV7131R",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -350,11 +349,8 @@ int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
                                       {0x34, 0x01}, {0x20, 0x17},
                                       {0x34, 0x01}, {0x46, 0x01});
 
-       if (err)
-               return -EIO;
-
        devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
-       if (devid < 0)
+       if (err || devid < 0)
                return -EIO;
 
        if (devid != 0x02)
index 9200845d011be5fae0f69eaf722c05dc6b326ea8..00b134ca0a3d56ac0d122bc15040c9f38cb99633 100644 (file)
@@ -55,45 +55,45 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
                           struct v4l2_control* ctrl)
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-       u8 data[5+1];
+       u8 data[2];
 
        switch (ctrl->id) {
        case V4L2_CID_EXPOSURE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[2];
+               ctrl->value = data[0];
                return 0;
        case V4L2_CID_GAIN:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case V4L2_CID_HFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x20 ? 1 : 0;
+               ctrl->value = data[1] & 0x20 ? 1 : 0;
                return 0;
        case V4L2_CID_VFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x80 ? 1 : 0;
+               ctrl->value = data[1] & 0x80 ? 1 : 0;
                return 0;
        case V4L2_CID_RED_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case V4L2_CID_BLUE_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+                                            data) < 0)
                        return -EIO;
                break;
        default:
@@ -105,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
        case V4L2_CID_RED_BALANCE:
        case V4L2_CID_BLUE_BALANCE:
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               ctrl->value = data[3] | (data[2] << 8);
+               ctrl->value = data[1] | (data[0] << 8);
                if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
                        ctrl->value -= 0x10;
                else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -223,7 +223,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
        .name = "MI-0343",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -332,20 +332,17 @@ static struct sn9c102_sensor mi0343 = {
 
 int sn9c102_probe_mi0343(struct sn9c102_device* cam)
 {
-       u8 data[5+1];
-       int err = 0;
-
-       err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-                                      {0x28, 0x17});
+       u8 data[2];
 
-       if (err)
+       if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                    {0x28, 0x17}))
                return -EIO;
 
        if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
                                     2, data) < 0)
                return -EIO;
 
-       if (data[4] != 0x32 || data[3] != 0xe3)
+       if (data[1] != 0x42 || data[0] != 0xe3)
                return -ENODEV;
 
        sn9c102_attach_sensor(cam, &mi0343);
index 64698acb0b15cd57feaa43a96bbfb6466b0729d9..f8d81d82e8d50e537ea85004b897e086aa1e4a97 100644 (file)
@@ -27,20 +27,105 @@ static int mi0360_init(struct sn9c102_device* cam)
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
 
-       err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
-                                      {0x0a, 0x14}, {0x40, 0x01},
-                                      {0x20, 0x17}, {0x07, 0x18},
-                                      {0xa0, 0x19}, {0x02, 0x1c},
-                                      {0x03, 0x1d}, {0x0f, 0x1e},
-                                      {0x0c, 0x1f}, {0x00, 0x20},
-                                      {0x10, 0x21}, {0x20, 0x22},
-                                      {0x30, 0x23}, {0x40, 0x24},
-                                      {0x50, 0x25}, {0x60, 0x26},
-                                      {0x70, 0x27}, {0x80, 0x28},
-                                      {0x90, 0x29}, {0xa0, 0x2a},
-                                      {0xb0, 0x2b}, {0xc0, 0x2c},
-                                      {0xd0, 0x2d}, {0xe0, 0x2e},
-                                      {0xf0, 0x2f}, {0xff, 0x30});
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+                                              {0x0a, 0x14}, {0x40, 0x01},
+                                              {0x20, 0x17}, {0x07, 0x18},
+                                              {0xa0, 0x19}, {0x02, 0x1c},
+                                              {0x03, 0x1d}, {0x0f, 0x1e},
+                                              {0x0c, 0x1f}, {0x00, 0x20},
+                                              {0x10, 0x21}, {0x20, 0x22},
+                                              {0x30, 0x23}, {0x40, 0x24},
+                                              {0x50, 0x25}, {0x60, 0x26},
+                                              {0x70, 0x27}, {0x80, 0x28},
+                                              {0x90, 0x29}, {0xa0, 0x2a},
+                                              {0xb0, 0x2b}, {0xc0, 0x2c},
+                                              {0xd0, 0x2d}, {0xe0, 0x2e},
+                                              {0xf0, 0x2f}, {0xff, 0x30});
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+                                              {0x00, 0x03}, {0x1a, 0x04},
+                                              {0x50, 0x05}, {0x20, 0x06},
+                                              {0x10, 0x07}, {0x03, 0x10},
+                                              {0x08, 0x14}, {0xa2, 0x17},
+                                              {0x47, 0x18}, {0x00, 0x19},
+                                              {0x1d, 0x1a}, {0x10, 0x1b},
+                                              {0x02, 0x1c}, {0x03, 0x1d},
+                                              {0x0f, 0x1e}, {0x0c, 0x1f},
+                                              {0x00, 0x20}, {0x29, 0x21},
+                                              {0x40, 0x22}, {0x54, 0x23},
+                                              {0x66, 0x24}, {0x76, 0x25},
+                                              {0x85, 0x26}, {0x94, 0x27},
+                                              {0xa1, 0x28}, {0xae, 0x29},
+                                              {0xbb, 0x2a}, {0xc7, 0x2b},
+                                              {0xd3, 0x2c}, {0xde, 0x2d},
+                                              {0xea, 0x2e}, {0xf4, 0x2f},
+                                              {0xff, 0x30}, {0x00, 0x3F},
+                                              {0xC7, 0x40}, {0x01, 0x41},
+                                              {0x44, 0x42}, {0x00, 0x43},
+                                              {0x44, 0x44}, {0x00, 0x45},
+                                              {0x44, 0x46}, {0x00, 0x47},
+                                              {0xC7, 0x48}, {0x01, 0x49},
+                                              {0xC7, 0x4A}, {0x01, 0x4B},
+                                              {0xC7, 0x4C}, {0x01, 0x4D},
+                                              {0x44, 0x4E}, {0x00, 0x4F},
+                                              {0x44, 0x50}, {0x00, 0x51},
+                                              {0x44, 0x52}, {0x00, 0x53},
+                                              {0xC7, 0x54}, {0x01, 0x55},
+                                              {0xC7, 0x56}, {0x01, 0x57},
+                                              {0xC7, 0x58}, {0x01, 0x59},
+                                              {0x44, 0x5A}, {0x00, 0x5B},
+                                              {0x44, 0x5C}, {0x00, 0x5D},
+                                              {0x44, 0x5E}, {0x00, 0x5F},
+                                              {0xC7, 0x60}, {0x01, 0x61},
+                                              {0xC7, 0x62}, {0x01, 0x63},
+                                              {0xC7, 0x64}, {0x01, 0x65},
+                                              {0x44, 0x66}, {0x00, 0x67},
+                                              {0x44, 0x68}, {0x00, 0x69},
+                                              {0x44, 0x6A}, {0x00, 0x6B},
+                                              {0xC7, 0x6C}, {0x01, 0x6D},
+                                              {0xC7, 0x6E}, {0x01, 0x6F},
+                                              {0xC7, 0x70}, {0x01, 0x71},
+                                              {0x44, 0x72}, {0x00, 0x73},
+                                              {0x44, 0x74}, {0x00, 0x75},
+                                              {0x44, 0x76}, {0x00, 0x77},
+                                              {0xC7, 0x78}, {0x01, 0x79},
+                                              {0xC7, 0x7A}, {0x01, 0x7B},
+                                              {0xC7, 0x7C}, {0x01, 0x7D},
+                                              {0x44, 0x7E}, {0x00, 0x7F},
+                                              {0x14, 0x84}, {0x00, 0x85},
+                                              {0x27, 0x86}, {0x00, 0x87},
+                                              {0x07, 0x88}, {0x00, 0x89},
+                                              {0xEC, 0x8A}, {0x0f, 0x8B},
+                                              {0xD8, 0x8C}, {0x0f, 0x8D},
+                                              {0x3D, 0x8E}, {0x00, 0x8F},
+                                              {0x3D, 0x90}, {0x00, 0x91},
+                                              {0xCD, 0x92}, {0x0f, 0x93},
+                                              {0xf7, 0x94}, {0x0f, 0x95},
+                                              {0x0C, 0x96}, {0x00, 0x97},
+                                              {0x00, 0x98}, {0x66, 0x99},
+                                              {0x05, 0x9A}, {0x00, 0x9B},
+                                              {0x04, 0x9C}, {0x00, 0x9D},
+                                              {0x08, 0x9E}, {0x00, 0x9F},
+                                              {0x2D, 0xC0}, {0x2D, 0xC1},
+                                              {0x3A, 0xC2}, {0x05, 0xC3},
+                                              {0x04, 0xC4}, {0x3F, 0xC5},
+                                              {0x00, 0xC6}, {0x00, 0xC7},
+                                              {0x50, 0xC8}, {0x3C, 0xC9},
+                                              {0x28, 0xCA}, {0xD8, 0xCB},
+                                              {0x14, 0xCC}, {0xEC, 0xCD},
+                                              {0x32, 0xCE}, {0xDD, 0xCF},
+                                              {0x32, 0xD0}, {0xDD, 0xD1},
+                                              {0x6A, 0xD2}, {0x50, 0xD3},
+                                              {0x00, 0xD4}, {0x00, 0xD5},
+                                              {0x00, 0xD6});
+               break;
+       default:
+               break;
+       }
 
        err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
                                         0x00, 0x01, 0, 0);
@@ -65,50 +150,50 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam,
                           struct v4l2_control* ctrl)
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
-       u8 data[5+1];
+       u8 data[2];
 
        switch (ctrl->id) {
        case V4L2_CID_EXPOSURE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[2];
+               ctrl->value = data[0];
                return 0;
        case V4L2_CID_GAIN:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_RED_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_BLUE_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3];
+               ctrl->value = data[1];
                return 0;
        case V4L2_CID_HFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x20 ? 1 : 0;
+               ctrl->value = data[1] & 0x20 ? 1 : 0;
                return 0;
        case V4L2_CID_VFLIP:
-               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
-                                            2+1, data) < 0)
+               if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+                                            data) < 0)
                        return -EIO;
-               ctrl->value = data[3] & 0x80 ? 1 : 0;
+               ctrl->value = data[1] & 0x80 ? 1 : 0;
                return 0;
        default:
                return -EINVAL;
@@ -178,8 +263,19 @@ static int mi0360_set_crop(struct sn9c102_device* cam,
 {
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
-       u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
-          v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+       u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+               break;
+       default:
+               break;
+       }
 
        err += sn9c102_write_reg(cam, h_start, 0x12);
        err += sn9c102_write_reg(cam, v_start, 0x13);
@@ -194,24 +290,30 @@ static int mi0360_set_pix_format(struct sn9c102_device* cam,
        struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
        int err = 0;
 
-       if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
-               err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
-                                                0x0a, 0x00, 0x02, 0, 0);
-               err += sn9c102_write_reg(cam, 0x20, 0x19);
-       } else {
+       if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
                err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
                                                 0x0a, 0x00, 0x05, 0, 0);
                err += sn9c102_write_reg(cam, 0x60, 0x19);
+               if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+                   sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+                       err += sn9c102_write_reg(cam, 0xa6, 0x17);
+       } else {
+               err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+                                                0x0a, 0x00, 0x02, 0, 0);
+               err += sn9c102_write_reg(cam, 0x20, 0x19);
+               if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+                   sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+                       err += sn9c102_write_reg(cam, 0xa2, 0x17);
        }
 
        return err;
 }
 
 
-static struct sn9c102_sensor mi0360 = {
+static const struct sn9c102_sensor mi0360 = {
        .name = "MI-0360",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
-       .supported_bridge = BRIDGE_SN9C103,
+       .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
        .frequency = SN9C102_I2C_100KHZ,
        .interface = SN9C102_I2C_2WIRES,
        .i2c_slave_id = 0x5d,
@@ -317,19 +419,31 @@ static struct sn9c102_sensor mi0360 = {
 
 int sn9c102_probe_mi0360(struct sn9c102_device* cam)
 {
-       u8 data[5+1];
-       int err;
 
-       err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
-                                      {0x28, 0x17});
-       if (err)
-               return -EIO;
+       u8 data[2];
+
+       switch (sn9c102_get_bridge(cam)) {
+       case BRIDGE_SN9C103:
+               if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                            {0x28, 0x17}))
+                       return -EIO;
+               break;
+       case BRIDGE_SN9C105:
+       case BRIDGE_SN9C120:
+               if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+                                            {0x01, 0x01}, {0x00, 0x01},
+                                            {0x28, 0x17}))
+                       return -EIO;
+               break;
+       default:
+               break;
+       }
 
        if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
-                                    2+1, data) < 0)
+                                    2, data) < 0)
                return -EIO;
 
-       if (data[2] != 0x82 || data[3] != 0x43)
+       if (data[0] != 0x82 || data[1] != 0x43)
                return -ENODEV;
 
        sn9c102_attach_sensor(cam, &mi0360);
index 31b6080b0615accb67dd25ca077072df5d6543f3..e6832347894fb273c622dc7abdc1e228a4f270cd 100644 (file)
@@ -29,9 +29,8 @@ static int ov7630_init(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x14},
-                                              {0x60, 0x17}, {0x0f, 0x18},
-                                              {0x50, 0x19});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+                                              {0x0f, 0x18}, {0x50, 0x19});
 
                err += sn9c102_i2c_write(cam, 0x12, 0x8d);
                err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -61,7 +60,6 @@ static int ov7630_init(struct sn9c102_device* cam)
                err += sn9c102_i2c_write(cam, 0x71, 0x00);
                err += sn9c102_i2c_write(cam, 0x74, 0x21);
                err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
-
                break;
        case BRIDGE_SN9C103:
                err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
@@ -253,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
        .name = "OV7630",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -408,19 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x01, 0x01},
-                                              {0x00, 0x01}, {0x28, 0x17});
-
+               err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+                                              {0x28, 0x17});
                break;
        case BRIDGE_SN9C103: /* do _not_ change anything! */
-               err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-                                              {0x42, 0x01}, {0x28, 0x17},
-                                              {0x44, 0x02});
+               err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+                                              {0x28, 0x17}, {0x44, 0x02});
                pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
-               if (err || pid < 0) { /* try a different initialization */
-                       err = sn9c102_write_reg(cam, 0x01, 0x01);
-                       err += sn9c102_write_reg(cam, 0x00, 0x01);
-               }
+               if (err || pid < 0) /* try a different initialization */
+                       err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+                                                       {0x00, 0x01});
                break;
        default:
                break;
index c898e948fe8d07ed70212b426d101094d6cb0fee..4b6474048a72976a66638f8896edc36dc5aa79e0 100644 (file)
@@ -104,8 +104,8 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x12, 0x80);
        err += sn9c102_i2c_write(cam, 0x11, 0x09);
        err += sn9c102_i2c_write(cam, 0x00, 0x0A);
-       err += sn9c102_i2c_write(cam, 0x01, 0x78);
-       err += sn9c102_i2c_write(cam, 0x02, 0x90);
+       err += sn9c102_i2c_write(cam, 0x01, 0x80);
+       err += sn9c102_i2c_write(cam, 0x02, 0x80);
        err += sn9c102_i2c_write(cam, 0x03, 0x00);
        err += sn9c102_i2c_write(cam, 0x04, 0x00);
        err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -122,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x10, 0x20);
        err += sn9c102_i2c_write(cam, 0x11, 0x03);
        err += sn9c102_i2c_write(cam, 0x12, 0x05);
-       err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+       err += sn9c102_i2c_write(cam, 0x13, 0xC7);
        err += sn9c102_i2c_write(cam, 0x14, 0x2C);
        err += sn9c102_i2c_write(cam, 0x15, 0x00);
        err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -162,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
        err += sn9c102_i2c_write(cam, 0x38, 0x02);
        err += sn9c102_i2c_write(cam, 0x39, 0x43);
        err += sn9c102_i2c_write(cam, 0x3A, 0x00);
-       err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+       err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
        err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
        err += sn9c102_i2c_write(cam, 0x3D, 0x99);
        err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -281,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
                        return -EIO;
                break;
        case V4L2_CID_DO_WHITE_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x02);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+                       return -EIO;
                ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
                break;
        case V4L2_CID_RED_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x05);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
        case V4L2_CID_BLUE_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x06);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
        case SN9C102_V4L2_CID_GREEN_BALANCE:
-               ctrl->value = sn9c102_pread_reg(cam, 0x07);
+               if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+                       return -EIO;
                ctrl->value &= 0x7f;
                break;
+       case SN9C102_V4L2_CID_BAND_FILTER:
+               if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+                       return -EIO;
+               ctrl->value &= 0x08;
+               break;
        case V4L2_CID_GAIN:
                if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
                        return -EIO;
-               ctrl->value &= 0x7f;
+               ctrl->value &= 0x1f;
                break;
        case V4L2_CID_AUTOGAIN:
                if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -335,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
        case SN9C102_V4L2_CID_GREEN_BALANCE:
                err += sn9c102_write_reg(cam, ctrl->value, 0x07);
                break;
+       case SN9C102_V4L2_CID_BAND_FILTER:
+               err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+               break;
        case V4L2_CID_GAIN:
-               err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+               err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
                break;
        case V4L2_CID_AUTOGAIN:
-               err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
-                                                   (ctrl->value << 1));
+               err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+                                                   (ctrl->value * 0x07));
                break;
        default:
                return -EINVAL;
@@ -386,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
        .name = "OV7660",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -401,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
                        .type = V4L2_CTRL_TYPE_INTEGER,
                        .name = "global gain",
                        .minimum = 0x00,
-                       .maximum = 0x7f,
+                       .maximum = 0x1f,
                        .step = 0x01,
-                       .default_value = 0x0a,
+                       .default_value = 0x09,
                        .flags = 0,
                },
                {
@@ -413,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0xff,
                        .step = 0x01,
-                       .default_value = 0x50,
+                       .default_value = 0x27,
                        .flags = 0,
                },
                {
@@ -433,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x1f,
+                       .default_value = 0x14,
                        .flags = 0,
                },
                {
@@ -443,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x1e,
+                       .default_value = 0x14,
                        .flags = 0,
                },
                {
@@ -453,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x01,
                        .step = 0x01,
-                       .default_value = 0x00,
+                       .default_value = 0x01,
                        .flags = 0,
                },
                {
@@ -463,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
                        .minimum = 0x00,
                        .maximum = 0x7f,
                        .step = 0x01,
-                       .default_value = 0x20,
+                       .default_value = 0x14,
+                       .flags = 0,
+               },
+               {
+                       .id = SN9C102_V4L2_CID_BAND_FILTER,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "band filter",
+                       .minimum = 0x00,
+                       .maximum = 0x01,
+                       .step = 0x01,
+                       .default_value = 0x00,
                        .flags = 0,
                },
        },
@@ -508,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
                return -EIO;
        if (pid != 0x76 || ver != 0x60)
                return -ENODEV;
+
        sn9c102_attach_sensor(cam, &ov7660);
 
        return 0;
index 67151964801fa6c59df309c8193aef86961908fe..360f2a848bc018212b8b8a3052f91d5787400cfe 100644 (file)
@@ -163,7 +163,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
        .name = "PAS106B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -273,23 +273,21 @@ static struct sn9c102_sensor pas106b = {
 
 int sn9c102_probe_pas106b(struct sn9c102_device* cam)
 {
-       int r0 = 0, r1 = 0, err;
+       int r0 = 0, r1 = 0;
        unsigned int pid = 0;
 
        /*
           Minimal initialization to enable the I2C communication
           NOTE: do NOT change the values!
        */
-       err = sn9c102_write_const_regs(cam,
-                                      {0x01, 0x01}, /* sensor power down */
-                                      {0x00, 0x01}, /* sensor power on */
-                                      {0x28, 0x17});/* sensor clock 24 MHz */
-       if (err)
+       if (sn9c102_write_const_regs(cam,
+                                    {0x01, 0x01}, /* sensor power down */
+                                    {0x00, 0x01}, /* sensor power on */
+                                   {0x28, 0x17})) /* sensor clock at 24 MHz */
                return -EIO;
 
        r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
        r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
        if (r0 < 0 || r1 < 0)
                return -EIO;
 
index c1b8d6b63b476b6974a42420900bb1bb942cdd5c..ca4a1506ed3df7cee74976afb2973d41152bf15e 100644 (file)
@@ -35,29 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
        switch (sn9c102_get_bridge(cam)) {
        case BRIDGE_SN9C101:
        case BRIDGE_SN9C102:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x10},
-                                              {0x00, 0x11}, {0x00, 0x14},
-                                              {0x20, 0x17}, {0x30, 0x19},
-                                              {0x09, 0x18});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+                                              {0x00, 0x14}, {0x20, 0x17},
+                                              {0x30, 0x19}, {0x09, 0x18});
                break;
        case BRIDGE_SN9C103:
-               err = sn9c102_write_const_regs(cam, {0x00, 0x02},
-                                              {0x00, 0x03}, {0x1a, 0x04},
-                                              {0x20, 0x05}, {0x20, 0x06},
-                                              {0x20, 0x07}, {0x00, 0x10},
-                                              {0x00, 0x11}, {0x00, 0x14},
-                                              {0x20, 0x17}, {0x30, 0x19},
-                                              {0x09, 0x18}, {0x02, 0x1c},
-                                              {0x03, 0x1d}, {0x0f, 0x1e},
-                                              {0x0c, 0x1f}, {0x00, 0x20},
-                                              {0x10, 0x21}, {0x20, 0x22},
-                                              {0x30, 0x23}, {0x40, 0x24},
-                                              {0x50, 0x25}, {0x60, 0x26},
-                                              {0x70, 0x27}, {0x80, 0x28},
-                                              {0x90, 0x29}, {0xa0, 0x2a},
-                                              {0xb0, 0x2b}, {0xc0, 0x2c},
-                                              {0xd0, 0x2d}, {0xe0, 0x2e},
-                                              {0xf0, 0x2f}, {0xff, 0x30});
+               err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+                                              {0x1a, 0x04}, {0x20, 0x05},
+                                              {0x20, 0x06}, {0x20, 0x07},
+                                              {0x00, 0x10}, {0x00, 0x11},
+                                              {0x00, 0x14}, {0x20, 0x17},
+                                              {0x30, 0x19}, {0x09, 0x18},
+                                              {0x02, 0x1c}, {0x03, 0x1d},
+                                              {0x0f, 0x1e}, {0x0c, 0x1f},
+                                              {0x00, 0x20}, {0x10, 0x21},
+                                              {0x20, 0x22}, {0x30, 0x23},
+                                              {0x40, 0x24}, {0x50, 0x25},
+                                              {0x60, 0x26}, {0x70, 0x27},
+                                              {0x80, 0x28}, {0x90, 0x29},
+                                              {0xa0, 0x2a}, {0xb0, 0x2b},
+                                              {0xc0, 0x2c}, {0xd0, 0x2d},
+                                              {0xe0, 0x2e}, {0xf0, 0x2f},
+                                              {0xff, 0x30});
                break;
        default:
                break;
@@ -197,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
        .name = "PAS202BCB",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -313,9 +312,8 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
                                               {0x28, 0x17});/* clock 24 MHz */
                break;
        case BRIDGE_SN9C103: /* do _not_ change anything! */
-               err = sn9c102_write_const_regs(cam, {0x09, 0x01},
-                                              {0x44, 0x01}, {0x44, 0x02},
-                                              {0x29, 0x17});
+               err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+                                              {0x44, 0x02}, {0x29, 0x17});
                break;
        default:
                break;
index 1bbf64c897a277f19d8a7c10b0e7a2104a34ebec..2d7d786b8430b7a5f236f191ca490d4679186667 100644 (file)
@@ -22,7 +22,7 @@
 #define _SN9C102_SENSOR_H_
 
 #include <linux/usb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <linux/device.h>
 #include <linux/stddef.h>
 #include <linux/errno.h>
@@ -74,7 +74,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
 /* Attach a probed sensor to the camera. */
 extern void
 sn9c102_attach_sensor(struct sn9c102_device* cam,
-                     struct sn9c102_sensor* sensor);
+                     const struct sn9c102_sensor* sensor);
 
 /*
    Read/write routines: they always return -1 on error, 0 or the read value
@@ -85,10 +85,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
 */
 
 /* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
-                                u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
-                               u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+                                const struct sn9c102_sensor*, u8 address,
+                                u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+                               const struct sn9c102_sensor*, u8 address);
 
 /*
    These must be used if and only if the sensor doesn't implement the standard
@@ -102,29 +103,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
    byte.
 */
 extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
-                                    struct sn9c102_sensor* sensor, u8 n,
+                                    const struct sn9c102_sensor* sensor, u8 n,
                                     u8 data0, u8 data1, u8 data2, u8 data3,
                                     u8 data4, u8 data5);
 extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
-                                   struct sn9c102_sensor* sensor, u8 data0,
-                                   u8 data1, u8 n, u8 buffer[]);
+                                   const struct sn9c102_sensor* sensor,
+                                   u8 data0, u8 data1, u8 n, u8 buffer[]);
 
 /* To be used after the sensor struct has been attached to the camera struct */
 extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
 extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
 
 /* I/O on registers in the bridge. Could be used by the sensor methods too */
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
 extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
 extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
                              int count);
 /*
- * Write multiple registers with constant values.  For example:
- * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- */
-#define sn9c102_write_const_regs(device, data...) \
-       ({ const static u8 _data[][2] = {data}; \
-       sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); })
+   Write multiple registers with constant values. For example:
+   sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+   Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...)                     \
+       ({ const static u8 _valreg[][2] = {data};                             \
+       sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
 
 /*****************************************************************************/
 
index 0e7ec8662c70cde24434a0b2e0c9a3aa12316eed..e7d2de2bace1096d837f16de2d03c39ce6c92f95 100644 (file)
@@ -88,7 +88,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
        .name = "TAS5110C1B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index 83a39e8b5e717ae439a4145884b616107546edab..d32fdbccdc5eb3fbbcc8fe5f083887f8049d284f 100644 (file)
@@ -68,7 +68,7 @@ static int tas5110d_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5110d = {
+static const struct sn9c102_sensor tas5110d = {
        .name = "TAS5110D",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index 50406503fc40c4019194bfb46541608e53f435ec..56fb1d575a8a6fd74a247de569a5e3d323c97080 100644 (file)
@@ -89,7 +89,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
 }
 
 
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
        .name = "TAS5130D1B",
        .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
        .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
index a0fd82b924f20780fb18c88eb3805e6e1a713f2d..e4cb99c1f94be8e930c4aa858ec4a5de69aab019 100644 (file)
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
 
 config USB_VICAM
        tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL
+       depends on VIDEO_V4L1 && EXPERIMENTAL
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
 
 config USB_IBMCAM
        tristate "USB IBM (Xirlink) C-it Camera support"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
 
 config USB_KONICAWC
        tristate "USB Konica Webcam support"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want support for webcams based on a Konica
@@ -39,7 +39,7 @@ config USB_KONICAWC
 
 config USB_QUICKCAM_MESSENGER
        tristate "USB Logitech Quickcam Messenger"
-       depends on USB && VIDEO_DEV && VIDEO_V4L1
+       depends on VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y or M here to enable support for the USB Logitech Quickcam
index c43a5d8990918bbffb510dbecfe47600360a392b..fc24ef05b3f31cf527b6fc850423cae317ad224b 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_USBVISION
        tristate "USB video devices based on Nogatech NT1003/1004/1005"
-       depends on I2C && VIDEO_V4L2 && USB
+       depends on I2C && VIDEO_V4L2
        select VIDEO_TUNER
        select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
        ---help---
index a861e150865e6c11ce5ff77264024124d0bc7b7d..ede8543818bfdfef8bdb3fa0bb86c0869cbf637a 100644 (file)
@@ -127,7 +127,7 @@ set_v4l_control(struct inode            *inode,
 
 /* ----------------------------------------------------------------- */
 
-static int palette2pixelformat[] = {
+const static unsigned int palette2pixelformat[] = {
        [VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
        [VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
        [VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
@@ -145,7 +145,7 @@ static int palette2pixelformat[] = {
        [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 };
 
-static unsigned int
+static unsigned int __attribute_pure__
 palette_to_pixelformat(unsigned int palette)
 {
        if (palette < ARRAY_SIZE(palette2pixelformat))
@@ -154,8 +154,8 @@ palette_to_pixelformat(unsigned int palette)
                return 0;
 }
 
-static unsigned int
-pixelformat_to_palette(int pixelformat)
+static unsigned int __attribute_const__
+pixelformat_to_palette(unsigned int pixelformat)
 {
        int     palette = 0;
        switch (pixelformat)
@@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCSPICT: /*  set tone controls & partial capture format  */
        {
                struct video_picture    *pict = arg;
+               int mem_err = 0, ovl_err = 0;
+
                memset(&fbuf2, 0, sizeof(fbuf2));
 
                set_v4l_control(inode, file,
@@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                                V4L2_CID_SATURATION, pict->colour, drv);
                set_v4l_control(inode, file,
                                V4L2_CID_WHITENESS, pict->whiteness, drv);
+               /*
+                * V4L1 uses this ioctl to set both memory capture and overlay
+                * pixel format, while V4L2 has two different ioctls for this.
+                * Some cards may not support one or the other, and may support
+                * different pixel formats for memory vs overlay.
+                */
 
                fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
                fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
                err = drv(inode, file, VIDIOC_G_FMT, fmt2);
-               if (err < 0)
+               /* If VIDIOC_G_FMT failed, then the driver likely doesn't
+                  support memory capture.  Trying to set the memory capture
+                  parameters would be pointless.  */
+               if (err < 0) {
                        dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
-               if (fmt2->fmt.pix.pixelformat !=
-                   palette_to_pixelformat(pict->palette)) {
+                       mem_err = -1000;  /* didn't even try */
+               } else if (fmt2->fmt.pix.pixelformat !=
+                        palette_to_pixelformat(pict->palette)) {
                        fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
                                pict->palette);
-                       err = drv(inode, file, VIDIOC_S_FMT, fmt2);
-                       if (err < 0)
-                               dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+                       mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+                       if (mem_err < 0)
+                               dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
+                                       mem_err);
                }
 
                err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
-               if (err < 0)
+               /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
+                  support overlay.  Trying to set the overlay parameters
+                  would be quite pointless.  */
+               if (err < 0) {
                        dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
-               if (fbuf2.fmt.pixelformat !=
-                   palette_to_pixelformat(pict->palette)) {
+                       ovl_err = -1000;  /* didn't even try */
+               } else if (fbuf2.fmt.pixelformat !=
+                        palette_to_pixelformat(pict->palette)) {
                        fbuf2.fmt.pixelformat = palette_to_pixelformat(
                                pict->palette);
-                       err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
-                       if (err < 0)
-                               dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
-                       err = 0; /* likely fails for non-root */
+                       ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
+                       if (ovl_err < 0)
+                               dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
+                                       ovl_err);
                }
+               if (ovl_err < 0 && mem_err < 0)
+                       /* ioctl failed, couldn't set either parameter */
+                       if (mem_err != -1000) {
+                           err = mem_err;
+                       } else if (ovl_err == -EPERM) {
+                           err = 0;
+                       } else {
+                           err = ovl_err;
+                       }
+               else
+                       err = 0;
                break;
        }
        case VIDIOCGTUNER: /*  get tuner information  */
index 459786ff459a97df7bd3c56e3140a29ac0282d96..a32dfbe0585af96de2c9acc126e5fd0e6fb1edd8 100644 (file)
@@ -702,9 +702,7 @@ videobuf_qbuf(struct videobuf_queue *q,
                dprintk(1,"qbuf: memory type is wrong.\n");
                goto done;
        }
-       if (buf->state == STATE_QUEUED ||
-           buf->state == STATE_PREPARED ||
-           buf->state == STATE_ACTIVE) {
+       if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
                dprintk(1,"qbuf: buffer is already queued or active.\n");
                goto done;
        }
index 5263b50463e11372ea37de29f2e62b7d9de97faf..b876aca69c73673fadb42f5e9388488d030c3eb4 100644 (file)
@@ -433,13 +433,43 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        int                  ret = -EINVAL;
 
        if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
-                               !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
+                               !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
                v4l_print_ioctl(vfd->name, cmd);
        }
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+       /***********************************************************
+        Handles calls to the obsoleted V4L1 API
+        Due to the nature of VIDIOCGMBUF, each driver that supports
+        V4L1 should implement its own handler for this ioctl.
+        ***********************************************************/
+
+       /* --- streaming capture ------------------------------------- */
+       if (cmd == VIDIOCGMBUF) {
+               struct video_mbuf *p=arg;
+
+               memset(p,0,sizeof(p));
+
+               if (!vfd->vidiocgmbuf)
+                       return ret;
+               ret=vfd->vidiocgmbuf(file, fh, p);
+               if (!ret)
+                       dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+                                               p->size, p->frames,
+                                               (unsigned long)p->offsets);
+               return ret;
+       }
+
+       /********************************************************
+        All other V4L1 calls are handled by v4l1_compat module.
+        Those calls will be translated into V4L2 calls, and
+        __video_do_ioctl will be called again, with one or more
+        V4L2 ioctls.
+        ********************************************************/
        if (_IOC_TYPE(cmd)=='v')
                return v4l_compat_translate_ioctl(inode,file,cmd,arg,
                                                __video_do_ioctl);
+#endif
 
        switch(cmd) {
        /* --- capabilities ------------------------------------------ */
@@ -791,24 +821,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                ret=vfd->vidioc_overlay(file, fh, *i);
                break;
        }
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-       /* --- streaming capture ------------------------------------- */
-       case VIDIOCGMBUF:
-       {
-               struct video_mbuf *p=arg;
-
-               memset(p,0,sizeof(p));
-
-               if (!vfd->vidiocgmbuf)
-                       break;
-               ret=vfd->vidiocgmbuf(file, fh, p);
-               if (!ret)
-                       dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
-                                               p->size, p->frames,
-                                               (unsigned long)p->offsets);
-               break;
-       }
-#endif
        case VIDIOC_G_FBUF:
        {
                struct v4l2_framebuffer *p=arg;
index a859a6920189e5cc62d64e864b6cfc79d995ca2d..47cd93f9c7de8555c7f181b0d17fc7a75793dbc6 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ZC0301
        tristate "USB ZC0301[P] Image Processor and Control Chip support"
-       depends on USB && VIDEO_V4L1
+       depends on VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on the ZC0301 or
          ZC0301P Image Processors and Control Chips.
index fa489b10c38cf8bd8da0a67ac63c5ea927333724..8a7f9e9fb8d853fa4c28e5c341fb4adbe572dbeb 100644 (file)
@@ -1898,8 +1898,12 @@ endmenu
 #      Gigabit Ethernet
 #
 
-menu "Ethernet (1000 Mbit)"
+menuconfig NETDEV_1000
+       bool "Ethernet (1000 Mbit)"
        depends on !UML
+       default y
+
+if NETDEV_1000
 
 config ACENIC
        tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
@@ -2326,14 +2330,18 @@ config ATL1
          To compile this driver as a module, choose M here.  The module
          will be called atl1.
 
-endmenu
+endif # NETDEV_1000
 
 #
 #      10 Gigabit Ethernet
 #
 
-menu "Ethernet (10000 Mbit)"
+menuconfig NETDEV_10000
+       bool "Ethernet (10000 Mbit)"
        depends on !UML
+       default y
+
+if NETDEV_10000
 
 config CHELSIO_T1
         tristate "Chelsio 10Gb Ethernet support"
@@ -2507,7 +2515,7 @@ config MLX4_DEBUG
          debug_level module parameter (which can also be set after
          the driver is loaded through sysfs).
 
-endmenu
+endif # NETDEV_10000
 
 source "drivers/net/tokenring/Kconfig"
 
index acf1c801a1b818b84314607ad9e4e884316d7a3d..af016d0ea1c67061123daabb9aba94137dabe454 100644 (file)
@@ -623,7 +623,7 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev)
                priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1;
        } else {
                err = request_irq(dev->pdev->irq, mlx4_interrupt,
-                                 SA_SHIRQ, DRV_NAME, dev);
+                                 IRQF_SHARED, DRV_NAME, dev);
                if (err)
                        goto err_out_async;
 
index 4e32bb678ea94b8e7ded7ad9b0311718849c3ca3..2c5c6d20e6e91c8ca8609e67e2ec474e9b53e797 100644 (file)
@@ -735,7 +735,7 @@ static int netxen_nic_open(struct net_device *netdev)
                }
                adapter->irq = adapter->ahw.pdev->irq;
                err = request_irq(adapter->ahw.pdev->irq, netxen_intr,
-                                 SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
+                                 IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name,
                                  adapter);
                if (err) {
                        printk(KERN_ERR "request_irq failed with: %d\n", err);
index 74f862001247b6feb20c21dd291d13ab2dcc180b..5d658bc9791ce147ab5bf2c8f8235bb1164c0640 100644 (file)
@@ -2,11 +2,9 @@
 # PCMCIA Network device configuration
 #
 
-menu "PCMCIA network device support"
-       depends on NETDEVICES && PCMCIA!=n
-
-config NET_PCMCIA
+menuconfig NET_PCMCIA
        bool "PCMCIA network device support"
+       depends on PCMCIA
        ---help---
          Say Y if you would like to include support for any PCMCIA or CardBus
          network adapters, then say Y to the driver for your particular card
@@ -21,9 +19,10 @@ config NET_PCMCIA
 
          If unsure, say N.
 
+if NET_PCMCIA
+
 config PCMCIA_3C589
        tristate "3Com 3c589 PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        help
          Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
          (PC-card) Ethernet card to your computer.
@@ -33,7 +32,6 @@ config PCMCIA_3C589
 
 config PCMCIA_3C574
        tristate "3Com 3c574 PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        help
          Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
          (PC-card) Fast Ethernet card to your computer.
@@ -43,7 +41,6 @@ config PCMCIA_3C574
 
 config PCMCIA_FMVJ18X
        tristate "Fujitsu FMV-J18x PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        select CRC32
        help
          Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
@@ -54,7 +51,6 @@ config PCMCIA_FMVJ18X
 
 config PCMCIA_PCNET
        tristate "NE2000 compatible PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        select CRC32
        help
          Say Y here if you intend to attach an NE2000 compatible PCMCIA
@@ -65,7 +61,6 @@ config PCMCIA_PCNET
 
 config PCMCIA_NMCLAN
        tristate "New Media PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        help
          Say Y here if you intend to attach a New Media Ethernet or LiveWire
          PCMCIA (PC-card) Ethernet card to your computer.
@@ -75,7 +70,6 @@ config PCMCIA_NMCLAN
 
 config PCMCIA_SMC91C92
        tristate "SMC 91Cxx PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        select CRC32
        select MII
        help
@@ -87,7 +81,6 @@ config PCMCIA_SMC91C92
 
 config PCMCIA_XIRC2PS
        tristate "Xircom 16-bit PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        help
          Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
          Ethernet or Fast Ethernet card to your computer.
@@ -97,7 +90,6 @@ config PCMCIA_XIRC2PS
 
 config PCMCIA_AXNET
        tristate "Asix AX88190 PCMCIA support"
-       depends on NET_PCMCIA && PCMCIA
        ---help---
          Say Y here if you intend to attach an Asix AX88190-based PCMCIA
          (PC-card) Fast Ethernet card to your computer.  These cards are
@@ -109,7 +101,7 @@ config PCMCIA_AXNET
 
 config ARCNET_COM20020_CS
        tristate "COM20020 ARCnet PCMCIA support"
-       depends on NET_PCMCIA && ARCNET_COM20020 && PCMCIA
+       depends on ARCNET_COM20020
        help
          Say Y here if you intend to attach this type of ARCnet PCMCIA card
          to your computer.
@@ -119,7 +111,7 @@ config ARCNET_COM20020_CS
 
 config PCMCIA_IBMTR
        tristate "IBM PCMCIA tokenring adapter support"
-       depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA && !64BIT
+       depends on IBMTR!=y && TR && !64BIT
        help
          Say Y here if you intend to attach this type of Token Ring PCMCIA
          card to your computer. You then also need to say Y to "Token Ring
@@ -128,5 +120,4 @@ config PCMCIA_IBMTR
          To compile this driver as a module, choose M here: the module will be
          called ibmtr_cs.
 
-endmenu
-
+endif # NET_PCMCIA
index c0d3101eb6a0a5891876fe32262191ccd98244be..09b6f259eb9225efbedec3d12523f48736c13a79 100644 (file)
@@ -2,70 +2,61 @@
 # PHY Layer Configuration
 #
 
-menu "PHY device support"
-       depends on !S390
-
-config PHYLIB
+menuconfig PHYLIB
        tristate "PHY Device support and infrastructure"
+       depends on !S390
        depends on NET_ETHERNET && (BROKEN || !S390)
        help
          Ethernet controllers are usually attached to PHY
          devices.  This option provides infrastructure for
          managing PHY devices.
 
+if PHYLIB
+
 comment "MII PHY device drivers"
-       depends on PHYLIB
 
 config MARVELL_PHY
        tristate "Drivers for Marvell PHYs"
-       depends on PHYLIB
        ---help---
          Currently has a driver for the 88E1011S
        
 config DAVICOM_PHY
        tristate "Drivers for Davicom PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports dm9161e and dm9131
 
 config QSEMI_PHY
        tristate "Drivers for Quality Semiconductor PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports the qs6612
 
 config LXT_PHY
        tristate "Drivers for the Intel LXT PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports the lxt970, lxt971
 
 config CICADA_PHY
        tristate "Drivers for the Cicada PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports the cis8204
+
 config VITESSE_PHY
         tristate "Drivers for the Vitesse PHYs"
-        depends on PHYLIB
         ---help---
           Currently supports the vsc8244
 
 config SMSC_PHY
        tristate "Drivers for SMSC PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports the LAN83C185 PHY
 
 config BROADCOM_PHY
        tristate "Drivers for Broadcom PHYs"
-       depends on PHYLIB
        ---help---
          Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
 
 config FIXED_PHY
        tristate "Drivers for PHY emulation on fixed speed/link"
-       depends on PHYLIB
        ---help---
          Adds the driver to PHY layer to cover the boards that do not have any PHY bound,
          but with the ability to manipulate the speed/link in software. The relevant MII
@@ -80,5 +71,4 @@ config FIXED_MII_100_FDX
        bool "Emulation for 100M Fdx fixed PHY behavior"
        depends on FIXED_PHY
 
-endmenu
-
+endif # PHYLIB
index 519baa38be8dcf767eac87b6f19843ef4ae21e52..7ed632db00d77dac9fb36df9629d74ea8e217b6d 100644 (file)
@@ -139,7 +139,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
        return (err < 0) ? err : 0;
 }
 
-static struct phy_driver dm9161_driver = {
+static struct phy_driver dm9161e_driver = {
        .phy_id         = 0x0181b880,
        .name           = "Davicom DM9161E",
        .phy_id_mask    = 0x0ffffff0,
@@ -147,7 +147,18 @@ static struct phy_driver dm9161_driver = {
        .config_init    = dm9161_config_init,
        .config_aneg    = dm9161_config_aneg,
        .read_status    = genphy_read_status,
-       .driver         = { .owner = THIS_MODULE,},
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver dm9161a_driver = {
+       .phy_id         = 0x0181b8a0,
+       .name           = "Davicom DM9161A",
+       .phy_id_mask    = 0x0ffffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .config_init    = dm9161_config_init,
+       .config_aneg    = dm9161_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE,},
 };
 
 static struct phy_driver dm9131_driver = {
@@ -160,31 +171,38 @@ static struct phy_driver dm9131_driver = {
        .read_status    = genphy_read_status,
        .ack_interrupt  = dm9161_ack_interrupt,
        .config_intr    = dm9161_config_intr,
-       .driver         = { .owner = THIS_MODULE,},
+       .driver         = { .owner = THIS_MODULE,},
 };
 
 static int __init davicom_init(void)
 {
        int ret;
 
-       ret = phy_driver_register(&dm9161_driver);
+       ret = phy_driver_register(&dm9161e_driver);
        if (ret)
                goto err1;
 
-       ret = phy_driver_register(&dm9131_driver);
+       ret = phy_driver_register(&dm9161a_driver);
        if (ret)
                goto err2;
+
+       ret = phy_driver_register(&dm9131_driver);
+       if (ret)
+               goto err3;
        return 0;
 
- err2: 
-       phy_driver_unregister(&dm9161_driver);
+ err3:
+       phy_driver_unregister(&dm9161a_driver);
+ err2:
+       phy_driver_unregister(&dm9161e_driver);
  err1:
        return ret;
 }
 
 static void __exit davicom_exit(void)
 {
-       phy_driver_unregister(&dm9161_driver);
+       phy_driver_unregister(&dm9161e_driver);
+       phy_driver_unregister(&dm9161a_driver);
        phy_driver_unregister(&dm9131_driver);
 }
 
index 290e1c1f30c6b0792953a6a285b6e60cfce03620..e3e6d410d72cdeef0d27bf10de6dce155bb6f201 100644 (file)
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.22.1"
+#define DRV_VERSION "2.0.23.1"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -281,6 +281,28 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        ("lro_out_of_sequence_pkts"),
        ("lro_flush_due_to_max_pkts"),
        ("lro_avg_aggr_pkts"),
+       ("mem_alloc_fail_cnt"),
+       ("watchdog_timer_cnt"),
+       ("mem_allocated"),
+       ("mem_freed"),
+       ("link_up_cnt"),
+       ("link_down_cnt"),
+       ("link_up_time"),
+       ("link_down_time"),
+       ("tx_tcode_buf_abort_cnt"),
+       ("tx_tcode_desc_abort_cnt"),
+       ("tx_tcode_parity_err_cnt"),
+       ("tx_tcode_link_loss_cnt"),
+       ("tx_tcode_list_proc_err_cnt"),
+       ("rx_tcode_parity_err_cnt"),
+       ("rx_tcode_abort_cnt"),
+       ("rx_tcode_parity_abort_cnt"),
+       ("rx_tcode_rda_fail_cnt"),
+       ("rx_tcode_unkn_prot_cnt"),
+       ("rx_tcode_fcs_err_cnt"),
+       ("rx_tcode_buf_size_err_cnt"),
+       ("rx_tcode_rxd_corrupt_cnt"),
+       ("rx_tcode_unkn_err_cnt")
 };
 
 #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
@@ -490,6 +512,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 
        struct mac_info *mac_control;
        struct config_param *config;
+       unsigned long long mem_allocated = 0;
 
        mac_control = &nic->mac_control;
        config = &nic->config;
@@ -519,6 +542,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                  "Malloc failed for list_info\n");
                        return -ENOMEM;
                }
+               mem_allocated += list_holder_size;
                memset(mac_control->fifos[i].list_info, 0, list_holder_size);
        }
        for (i = 0; i < config->tx_fifo_num; i++) {
@@ -565,6 +589,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                        DBG_PRINT(INFO_DBG, "failed for TxDL\n");
                                        return -ENOMEM;
                                }
+                               mem_allocated += PAGE_SIZE;
                        }
                        while (k < lst_per_page) {
                                int l = (j * lst_per_page) + k;
@@ -582,6 +607,7 @@ static int init_shared_mem(struct s2io_nic *nic)
        nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
        if (!nic->ufo_in_band_v)
                return -ENOMEM;
+        mem_allocated += (size * sizeof(u64));
 
        /* Allocation and initialization of RXDs in Rings */
        size = 0;
@@ -639,6 +665,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                rx_blocks->block_virt_addr = tmp_v_addr;
                                return -ENOMEM;
                        }
+                       mem_allocated += size;
                        memset(tmp_v_addr, 0, size);
                        rx_blocks->block_virt_addr = tmp_v_addr;
                        rx_blocks->block_dma_addr = tmp_p_addr;
@@ -647,6 +674,8 @@ static int init_shared_mem(struct s2io_nic *nic)
                                                  GFP_KERNEL);
                        if (!rx_blocks->rxds)
                                return -ENOMEM;
+                       mem_allocated += 
+                       (sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
                        for (l=0; l<rxd_count[nic->rxd_mode];l++) {
                                rx_blocks->rxds[l].virt_addr =
                                        rx_blocks->block_virt_addr +
@@ -689,6 +718,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                                     GFP_KERNEL);
                        if (!mac_control->rings[i].ba)
                                return -ENOMEM;
+                       mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt);
                        for (j = 0; j < blk_cnt; j++) {
                                int k = 0;
                                mac_control->rings[i].ba[j] =
@@ -697,6 +727,8 @@ static int init_shared_mem(struct s2io_nic *nic)
                                                GFP_KERNEL);
                                if (!mac_control->rings[i].ba[j])
                                        return -ENOMEM;
+                               mem_allocated += (sizeof(struct buffAdd) *  \
+                                       (rxd_count[nic->rxd_mode] + 1));
                                while (k != rxd_count[nic->rxd_mode]) {
                                        ba = &mac_control->rings[i].ba[j][k];
 
@@ -704,6 +736,8 @@ static int init_shared_mem(struct s2io_nic *nic)
                                            (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
                                        if (!ba->ba_0_org)
                                                return -ENOMEM;
+                                       mem_allocated += 
+                                               (BUF0_LEN + ALIGN_SIZE);
                                        tmp = (unsigned long)ba->ba_0_org;
                                        tmp += ALIGN_SIZE;
                                        tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -713,6 +747,8 @@ static int init_shared_mem(struct s2io_nic *nic)
                                            (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
                                        if (!ba->ba_1_org)
                                                return -ENOMEM;
+                                       mem_allocated 
+                                               += (BUF1_LEN + ALIGN_SIZE);
                                        tmp = (unsigned long) ba->ba_1_org;
                                        tmp += ALIGN_SIZE;
                                        tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -736,6 +772,7 @@ static int init_shared_mem(struct s2io_nic *nic)
                 */
                return -ENOMEM;
        }
+       mem_allocated += size;
        mac_control->stats_mem_sz = size;
 
        tmp_v_addr = mac_control->stats_mem;
@@ -743,7 +780,7 @@ static int init_shared_mem(struct s2io_nic *nic)
        memset(tmp_v_addr, 0, size);
        DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name,
                  (unsigned long long) tmp_p_addr);
-
+       mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
        return SUCCESS;
 }
 
@@ -757,12 +794,14 @@ static int init_shared_mem(struct s2io_nic *nic)
 static void free_shared_mem(struct s2io_nic *nic)
 {
        int i, j, blk_cnt, size;
+       u32 ufo_size = 0;
        void *tmp_v_addr;
        dma_addr_t tmp_p_addr;
        struct mac_info *mac_control;
        struct config_param *config;
        int lst_size, lst_per_page;
        struct net_device *dev = nic->dev;
+       int page_num = 0;
 
        if (!nic)
                return;
@@ -774,8 +813,9 @@ static void free_shared_mem(struct s2io_nic *nic)
        lst_per_page = PAGE_SIZE / lst_size;
 
        for (i = 0; i < config->tx_fifo_num; i++) {
-               int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
-                                               lst_per_page);
+               ufo_size += config->tx_cfg[i].fifo_len;
+               page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
+                                                       lst_per_page);
                for (j = 0; j < page_num; j++) {
                        int mem_blks = (j * lst_per_page);
                        if (!mac_control->fifos[i].list_info)
@@ -790,6 +830,8 @@ static void free_shared_mem(struct s2io_nic *nic)
                                            mac_control->fifos[i].
                                            list_info[mem_blks].
                                            list_phy_addr);
+                       nic->mac_control.stats_info->sw_stat.mem_freed 
+                                               += PAGE_SIZE;
                }
                /* If we got a zero DMA address during allocation,
                 * free the page now
@@ -803,8 +845,12 @@ static void free_shared_mem(struct s2io_nic *nic)
                                dev->name);
                        DBG_PRINT(INIT_DBG, "Virtual address %p\n",
                                mac_control->zerodma_virt_addr);
+                       nic->mac_control.stats_info->sw_stat.mem_freed 
+                                               += PAGE_SIZE;
                }
                kfree(mac_control->fifos[i].list_info);
+               nic->mac_control.stats_info->sw_stat.mem_freed += 
+               (nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold));
        }
 
        size = SIZE_OF_BLOCK;
@@ -819,7 +865,10 @@ static void free_shared_mem(struct s2io_nic *nic)
                                break;
                        pci_free_consistent(nic->pdev, size,
                                            tmp_v_addr, tmp_p_addr);
+                       nic->mac_control.stats_info->sw_stat.mem_freed += size;
                        kfree(mac_control->rings[i].rx_blocks[j].rxds);
+                       nic->mac_control.stats_info->sw_stat.mem_freed += 
+                       ( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
                }
        }
 
@@ -836,12 +885,20 @@ static void free_shared_mem(struct s2io_nic *nic)
                                        struct buffAdd *ba =
                                                &mac_control->rings[i].ba[j][k];
                                        kfree(ba->ba_0_org);
+                                       nic->mac_control.stats_info->sw_stat.\
+                                       mem_freed += (BUF0_LEN + ALIGN_SIZE);
                                        kfree(ba->ba_1_org);
+                                       nic->mac_control.stats_info->sw_stat.\
+                                       mem_freed += (BUF1_LEN + ALIGN_SIZE);
                                        k++;
                                }
                                kfree(mac_control->rings[i].ba[j]);
+                               nic->mac_control.stats_info->sw_stat.mem_freed                          += (sizeof(struct buffAdd) * 
+                               (rxd_count[nic->rxd_mode] + 1));
                        }
                        kfree(mac_control->rings[i].ba);
+                       nic->mac_control.stats_info->sw_stat.mem_freed += 
+                       (sizeof(struct buffAdd *) * blk_cnt);
                }
        }
 
@@ -850,9 +907,14 @@ static void free_shared_mem(struct s2io_nic *nic)
                                    mac_control->stats_mem_sz,
                                    mac_control->stats_mem,
                                    mac_control->stats_mem_phy);
+               nic->mac_control.stats_info->sw_stat.mem_freed += 
+                       mac_control->stats_mem_sz;
        }
-       if (nic->ufo_in_band_v)
+       if (nic->ufo_in_band_v) {
                kfree(nic->ufo_in_band_v);
+               nic->mac_control.stats_info->sw_stat.mem_freed 
+                       += (ufo_size * sizeof(u64));
+       }
 }
 
 /**
@@ -2122,10 +2184,12 @@ static void free_tx_buffers(struct s2io_nic *nic)
 
        for (i = 0; i < config->tx_fifo_num; i++) {
                for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
-                       txdp = (struct TxD *) mac_control->fifos[i].list_info[j].
-                           list_virt_addr;
+                       txdp = (struct TxD *) \
+                       mac_control->fifos[i].list_info[j].list_virt_addr;
                        skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
                        if (skb) {
+                               nic->mac_control.stats_info->sw_stat.mem_freed 
+                                       += skb->truesize;
                                dev_kfree_skb(skb);
                                cnt++;
                        }
@@ -2186,11 +2250,14 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
        /* skb_shinfo(skb)->frag_list will have L4 data payload */
        skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
        if (skb_shinfo(skb)->frag_list == NULL) {
+               nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
                return -ENOMEM ;
        }
        frag_list = skb_shinfo(skb)->frag_list;
        skb->truesize += frag_list->truesize;
+       nic->mac_control.stats_info->sw_stat.mem_allocated 
+               += frag_list->truesize;
        frag_list->next = NULL;
        tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
        frag_list->data = tmp;
@@ -2319,8 +2386,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                wmb();
                                first_rxdp->Control_1 |= RXD_OWN_XENA;
                        }
+                       nic->mac_control.stats_info->sw_stat. \
+                               mem_alloc_fail_cnt++;
                        return -ENOMEM ;
                }
+               nic->mac_control.stats_info->sw_stat.mem_allocated 
+                       += skb->truesize;
                if (nic->rxd_mode == RXD_MODE_1) {
                        /* 1 buffer mode - normal operation mode */
                        memset(rxdp, 0, sizeof(struct RxD1));
@@ -2328,7 +2399,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                        ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
                            (nic->pdev, skb->data, size - NET_IP_ALIGN,
                                PCI_DMA_FROMDEVICE);
-                       rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
+                       rxdp->Control_2 = 
+                               SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 
                } else if (nic->rxd_mode >= RXD_MODE_3A) {
                        /*
@@ -2342,7 +2414,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                         * payload
                         */
 
-                       /* save the buffer pointers to avoid frequent dma mapping */
+                       /* save buffer pointers to avoid frequent dma mapping */
                        Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
                        Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
                        memset(rxdp, 0, sizeof(struct RxD3));
@@ -2364,7 +2436,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                                           PCI_DMA_FROMDEVICE);
                        else
                                pci_dma_sync_single_for_device(nic->pdev,
-                                   (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+                               (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
                                    BUF0_LEN, PCI_DMA_FROMDEVICE);
                        rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
                        if (nic->rxd_mode == RXD_MODE_3B) {
@@ -2391,6 +2463,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
                        } else {
                                /* 3 buffer mode */
                                if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
+                                       nic->mac_control.stats_info->sw_stat.\
+                                       mem_freed += skb->truesize;
                                        dev_kfree_skb_irq(skb);
                                        if (first_rxdp) {
                                                wmb();
@@ -2491,6 +2565,7 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
                                PCI_DMA_FROMDEVICE);
                        memset(rxdp, 0, sizeof(struct RxD3));
                }
+               sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
                dev_kfree_skb(skb);
                atomic_dec(&sp->rx_bufs_left[ring_no]);
        }
@@ -2820,13 +2895,35 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
                                nic->mac_control.stats_info->sw_stat.
                                                parity_err_cnt++;
                        }
-                       if ((err >> 48) == 0xA) {
-                               DBG_PRINT(TX_DBG, "TxD returned due \
-                                               to loss of link\n");
-                       }
-                       else {
-                               DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err);
-                       }
+
+                       /* update t_code statistics */
+                       err >>= 48;
+                       switch(err) {
+                               case 2:
+                                       nic->mac_control.stats_info->sw_stat.
+                                                       tx_buf_abort_cnt++;
+                               break;
+
+                               case 3:
+                                       nic->mac_control.stats_info->sw_stat.
+                                                       tx_desc_abort_cnt++;
+                               break;
+
+                               case 7:
+                                       nic->mac_control.stats_info->sw_stat.
+                                                       tx_parity_err_cnt++;
+                               break;
+
+                               case 10:
+                                       nic->mac_control.stats_info->sw_stat.
+                                                       tx_link_loss_cnt++;
+                               break;
+
+                               case 15:
+                                       nic->mac_control.stats_info->sw_stat.
+                                                       tx_list_proc_err_cnt++;
+                               break;
+                        }
                }
 
                skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
@@ -2839,6 +2936,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 
                /* Updating the statistics block */
                nic->stats.tx_bytes += skb->len;
+               nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
                dev_kfree_skb_irq(skb);
 
                get_info.offset++;
@@ -3314,7 +3412,9 @@ static void s2io_reset(struct s2io_nic * sp)
        u16 subid, pci_cmd;
        int i;
        u16 val16;
-       unsigned long long reset_cnt = 0;
+       unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt;
+       unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
+
        DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
                        __FUNCTION__, sp->dev->name);
 
@@ -3380,11 +3480,26 @@ new_way:
 
        /* Reset device statistics maintained by OS */
        memset(&sp->stats, 0, sizeof (struct net_device_stats));
-       /* save reset count */
+       
+       up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt;
+       down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt;
+       up_time = sp->mac_control.stats_info->sw_stat.link_up_time;
+       down_time = sp->mac_control.stats_info->sw_stat.link_down_time;
        reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
+       mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated;
+       mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed;
+       watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt;
+       /* save link up/down time/cnt, reset/memory/watchdog cnt */
        memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
-       /* restore reset count */
+       /* restore link up/down time/cnt, reset/memory/watchdog cnt */
+       sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt;
+       sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt;
+       sp->mac_control.stats_info->sw_stat.link_up_time = up_time;
+       sp->mac_control.stats_info->sw_stat.link_down_time = down_time;
        sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
+       sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt;
+       sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt;
+       sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt;
 
        /* SXE-002: Configure link and activity LED to turn it off */
        subid = sp->pdev->subsystem_device;
@@ -3672,19 +3787,29 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
                               GFP_KERNEL);
        if (nic->entries == NULL) {
-               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
+                       __FUNCTION__);
+               nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                return -ENOMEM;
        }
-       memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+       nic->mac_control.stats_info->sw_stat.mem_allocated 
+               += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+       memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
 
        nic->s2io_entries =
                kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
                                   GFP_KERNEL);
        if (nic->s2io_entries == NULL) {
-               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+               DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", 
+                       __FUNCTION__);
+               nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                kfree(nic->entries);
+               nic->mac_control.stats_info->sw_stat.mem_freed 
+                       += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
                return -ENOMEM;
        }
+        nic->mac_control.stats_info->sw_stat.mem_allocated 
+               += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
        memset(nic->s2io_entries, 0,
               MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
 
@@ -3708,7 +3833,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
                rx_mat = readq(&bar0->rx_mat);
                for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
                        rx_mat |= RX_MAT_SET(j, msix_indx);
-                       nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+                       nic->s2io_entries[msix_indx].arg 
+                               = &nic->mac_control.rings[j];
                        nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
                        nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
                }
@@ -3717,7 +3843,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
                tx_mat = readq(&bar0->tx_mat0_n[7]);
                for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
                        tx_mat |= TX_MAT_SET(i, msix_indx);
-                       nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+                       nic->s2io_entries[msix_indx].arg 
+                               = &nic->mac_control.rings[j];
                        nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
                        nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
                }
@@ -3734,7 +3861,11 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
        if (ret) {
                DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
                kfree(nic->entries);
+               nic->mac_control.stats_info->sw_stat.mem_freed 
+                       += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
                kfree(nic->s2io_entries);
+               nic->mac_control.stats_info->sw_stat.mem_freed 
+               += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
                nic->entries = NULL;
                nic->s2io_entries = NULL;
                nic->avail_msix_vectors = 0;
@@ -3802,10 +3933,16 @@ static int s2io_open(struct net_device *dev)
 
 hw_init_failed:
        if (sp->intr_type == MSI_X) {
-               if (sp->entries)
+               if (sp->entries) {
                        kfree(sp->entries);
-               if (sp->s2io_entries)
+                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                       += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+               }
+               if (sp->s2io_entries) {
                        kfree(sp->s2io_entries);
+                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                       += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+               }
        }
        return err;
 }
@@ -3866,6 +4003,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        config = &sp->config;
 
        DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name);
+
+       if (unlikely(skb->len <= 0)) {
+               DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
+               dev_kfree_skb_any(skb);
+               return 0;
+}
+
        spin_lock_irqsave(&sp->tx_lock, flags);
        if (atomic_read(&sp->card_state) == CARD_DOWN) {
                DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
@@ -3876,7 +4020,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        queue = 0;
-
        /* Get Fifo number to Transmit based on vlan priority */
        if (sp->vlgrp && vlan_tx_tag_present(skb)) {
                vlan_tag = vlan_tx_tag_get(skb);
@@ -3900,14 +4043,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
 
-       /* A buffer with no data will be dropped */
-       if (!skb->len) {
-               DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
-               dev_kfree_skb(skb);
-               spin_unlock_irqrestore(&sp->tx_lock, flags);
-               return 0;
-       }
-
        offload_type = s2io_offload_type(skb);
        if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
                txdp->Control_1 |= TXD_TCP_LSO_EN;
@@ -4003,7 +4138,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                          put_off, get_off);
                netif_stop_queue(dev);
        }
-
+       mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
        dev->trans_start = jiffies;
        spin_unlock_irqrestore(&sp->tx_lock, flags);
 
@@ -4775,6 +4910,40 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
        return 0;
 }
 
+static void s2io_ethtool_gringparam(struct net_device *dev,
+                                    struct ethtool_ringparam *ering)
+{
+       struct s2io_nic *sp = dev->priv;
+       int i,tx_desc_count=0,rx_desc_count=0;
+
+       if (sp->rxd_mode == RXD_MODE_1)
+               ering->rx_max_pending = MAX_RX_DESC_1;
+       else if (sp->rxd_mode == RXD_MODE_3B)
+               ering->rx_max_pending = MAX_RX_DESC_2;
+       else if (sp->rxd_mode == RXD_MODE_3A)
+               ering->rx_max_pending = MAX_RX_DESC_3;
+
+       ering->tx_max_pending = MAX_TX_DESC;
+       for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+               tx_desc_count += sp->config.tx_cfg[i].fifo_len;
+       }
+       DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
+       ering->tx_pending = tx_desc_count;
+       rx_desc_count = 0;
+       for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+               rx_desc_count += sp->config.rx_cfg[i].num_rxd;
+       }
+       ering->rx_pending = rx_desc_count;
+
+       ering->rx_mini_max_pending = 0;
+       ering->rx_mini_pending = 0;
+       if(sp->rxd_mode == RXD_MODE_1)
+               ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
+       else if (sp->rxd_mode == RXD_MODE_3B)
+               ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
+       ering->rx_jumbo_pending = rx_desc_count;
+}
+
 /**
  * s2io_ethtool_getpause_data -Pause frame frame generation and reception.
  * @sp : private member of the device structure, which is a pointer to the
@@ -4981,8 +5150,11 @@ static void s2io_vpd_read(struct s2io_nic *nic)
        strcpy(nic->serial_num, "NOT AVAILABLE");
 
        vpd_data = kmalloc(256, GFP_KERNEL);
-       if (!vpd_data)
+       if (!vpd_data) {
+               nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                return;
+       }
+       nic->mac_control.stats_info->sw_stat.mem_allocated += 256;
 
        for (i = 0; i < 256; i +=4 ) {
                pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
@@ -5022,6 +5194,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
                memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
        }
        kfree(vpd_data);
+       nic->mac_control.stats_info->sw_stat.mem_freed += 256;
 }
 
 /**
@@ -5742,6 +5915,30 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
        }
        else
                tmp_stats[i++] = 0;
+       tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
+       tmp_stats[i++] = stat_info->sw_stat.mem_freed;
+       tmp_stats[i++] = stat_info->sw_stat.link_up_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.link_down_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.link_up_time;
+       tmp_stats[i++] = stat_info->sw_stat.link_down_time;
+
+       tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt;
+
+       tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
+       tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
 }
 
 static int s2io_ethtool_get_regs_len(struct net_device *dev)
@@ -5854,6 +6051,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .get_eeprom_len = s2io_get_eeprom_len,
        .get_eeprom = s2io_ethtool_geeprom,
        .set_eeprom = s2io_ethtool_seeprom,
+       .get_ringparam = s2io_ethtool_gringparam,
        .get_pauseparam = s2io_ethtool_getpause_data,
        .set_pauseparam = s2io_ethtool_setpause_data,
        .get_rx_csum = s2io_ethtool_get_rx_csum,
@@ -5962,7 +6160,7 @@ static void s2io_tasklet(unsigned long dev_addr)
                        if (ret == -ENOMEM) {
                                DBG_PRINT(INFO_DBG, "%s: Out of ",
                                          dev->name);
-                               DBG_PRINT(ERR_DBG, "memory in tasklet\n");
+                               DBG_PRINT(INFO_DBG, "memory in tasklet\n");
                                break;
                        } else if (ret == -EFILL) {
                                DBG_PRINT(INFO_DBG,
@@ -6077,9 +6275,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
                                DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
-                               DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
+                               DBG_PRINT(INFO_DBG, "memory to allocate ");
+                               DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n");
+                               sp->mac_control.stats_info->sw_stat. \
+                                       mem_alloc_fail_cnt++;
                                return -ENOMEM ;
                        }
+                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                               += (*skb)->truesize;
                        /* storing the mapped addr in a temp variable
                         * such it will be used for next rxd whose
                         * Host Control is NULL
@@ -6099,10 +6302,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                } else {
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
-                               DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
-                                       dev->name);
+                               DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+                               DBG_PRINT(INFO_DBG, "memory to allocate ");
+                               DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n");
+                               sp->mac_control.stats_info->sw_stat. \
+                                       mem_alloc_fail_cnt++;
                                return -ENOMEM;
                        }
+                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                               += (*skb)->truesize;
                        ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
                                pci_map_single(sp->pdev, (*skb)->data,
                                               dev->mtu + 4,
@@ -6126,10 +6334,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                } else {
                        *skb = dev_alloc_skb(size);
                        if (!(*skb)) {
-                               DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
-                                         dev->name);
+                               DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+                               DBG_PRINT(INFO_DBG, "memory to allocate ");
+                               DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
+                               sp->mac_control.stats_info->sw_stat. \
+                                       mem_alloc_fail_cnt++;
                                return -ENOMEM;
                        }
+                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                               += (*skb)->truesize;
                        ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
                                pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
                                               PCI_DMA_FROMDEVICE);
@@ -6147,10 +6360,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                        if (skb_shinfo(*skb)->frag_list == NULL) {
                                DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
                                          failed\n ", dev->name);
+                               sp->mac_control.stats_info->sw_stat. \
+                                       mem_alloc_fail_cnt++;
                                return -ENOMEM ;
                        }
                        frag_list = skb_shinfo(*skb)->frag_list;
                        frag_list->next = NULL;
+                       sp->mac_control.stats_info->sw_stat.mem_allocated 
+                               += frag_list->truesize;
                        /*
                         * Buffer-2 receives L4 data payload
                         */
@@ -6566,6 +6783,7 @@ static void s2io_tx_watchdog(struct net_device *dev)
        struct s2io_nic *sp = dev->priv;
 
        if (netif_carrier_ok(dev)) {
+               sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++;
                schedule_work(&sp->rst_timer_task);
                sp->mac_control.stats_info->sw_stat.soft_reset_cnt++;
        }
@@ -6606,7 +6824,53 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                if (err & 0x1) {
                        sp->mac_control.stats_info->sw_stat.parity_err_cnt++;
                }
+               err >>= 48;
+               switch(err) {
+                       case 1:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_parity_err_cnt++;
+                       break;
 
+                       case 2:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_abort_cnt++;
+                       break;
+
+                       case 3:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_parity_abort_cnt++;
+                       break;
+
+                       case 4:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_rda_fail_cnt++;
+                       break;
+
+                       case 5:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_unkn_prot_cnt++;
+                       break;
+
+                       case 6:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_fcs_err_cnt++;
+                       break;
+
+                       case 7:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_buf_size_err_cnt++;
+                       break;
+
+                       case 8:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_rxd_corrupt_cnt++;
+                       break;
+
+                       case 15:
+                               sp->mac_control.stats_info->sw_stat.
+                               rx_unkn_err_cnt++;
+                       break;
+               }
                /*
                * Drop the packet if bad transfer code. Exception being
                * 0x5, which could be due to unsupported IPv6 extension header.
@@ -6614,10 +6878,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                * Note that in this case, since checksum will be incorrect,
                * stack will validate the same.
                */
-               if (err && ((err >> 48) != 0x5)) {
+               if (err != 0x5) {
                        DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n",
                                dev->name, err);
                        sp->stats.rx_crc_errors++;
+                       sp->mac_control.stats_info->sw_stat.mem_freed 
+                               += skb->truesize;
                        dev_kfree_skb(skb);
                        atomic_dec(&sp->rx_bufs_left[ring_no]);
                        rxdp->Host_Control = 0;
@@ -6627,7 +6893,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 
        /* Updating statistics */
        rxdp->Host_Control = 0;
-       sp->stats.rx_packets++;
        if (sp->rxd_mode == RXD_MODE_1) {
                int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
 
@@ -6731,7 +6996,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
        } else {
                skb->ip_summed = CHECKSUM_NONE;
        }
-
+       sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
        if (!sp->lro) {
                skb->protocol = eth_type_trans(skb, dev);
                if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) &&
@@ -6780,12 +7045,21 @@ static void s2io_link(struct s2io_nic * sp, int link)
                if (link == LINK_DOWN) {
                        DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
                        netif_carrier_off(dev);
+                       if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
+                       sp->mac_control.stats_info->sw_stat.link_up_time = 
+                               jiffies - sp->start_time;
+                       sp->mac_control.stats_info->sw_stat.link_down_cnt++;
                } else {
                        DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
+                       if (sp->mac_control.stats_info->sw_stat.link_down_cnt)
+                       sp->mac_control.stats_info->sw_stat.link_down_time = 
+                               jiffies - sp->start_time;
+                       sp->mac_control.stats_info->sw_stat.link_up_cnt++;
                        netif_carrier_on(dev);
                }
        }
        sp->last_link_state = link;
+       sp->start_time = jiffies;
 }
 
 /**
index a656d18b33df200fa34c9af8f3c648c804e8c213..54baa0b8ec7c937a17b8f2ae984e2799831cb9c6 100644 (file)
@@ -95,6 +95,32 @@ struct swStat {
        unsigned long long flush_max_pkts;
        unsigned long long sum_avg_pkts_aggregated;
        unsigned long long num_aggregations;
+       /* Other statistics */
+       unsigned long long mem_alloc_fail_cnt;
+       unsigned long long watchdog_timer_cnt;
+       unsigned long long mem_allocated;
+       unsigned long long mem_freed;
+       unsigned long long link_up_cnt;
+       unsigned long long link_down_cnt;
+       unsigned long long link_up_time;
+       unsigned long long link_down_time;
+
+       /* Transfer Code statistics */
+       unsigned long long tx_buf_abort_cnt;
+       unsigned long long tx_desc_abort_cnt;
+       unsigned long long tx_parity_err_cnt;
+       unsigned long long tx_link_loss_cnt;
+       unsigned long long tx_list_proc_err_cnt;
+
+       unsigned long long rx_parity_err_cnt;
+       unsigned long long rx_abort_cnt;
+       unsigned long long rx_parity_abort_cnt;
+       unsigned long long rx_rda_fail_cnt;
+       unsigned long long rx_unkn_prot_cnt;
+       unsigned long long rx_fcs_err_cnt;
+       unsigned long long rx_buf_size_err_cnt;
+       unsigned long long rx_rxd_corrupt_cnt;
+       unsigned long long rx_unkn_err_cnt;
 };
 
 /* Xpak releated alarm and warnings */
@@ -308,6 +334,11 @@ struct stat_block {
 #define MAX_TX_FIFOS 8
 #define MAX_RX_RINGS 8
 
+#define MAX_RX_DESC_1  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
+#define MAX_RX_DESC_2  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_RX_DESC_3  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_TX_DESC    (MAX_AVAILABLE_TXDS)
+
 /* FIFO mappings for all possible number of fifos configured */
 static int fifo_map[][MAX_TX_FIFOS] = {
        {0, 0, 0, 0, 0, 0, 0, 0},
@@ -819,6 +850,7 @@ struct s2io_nic {
 #define        LINK_UP         2
 
        int task_flag;
+       unsigned long long start_time;
 #define CARD_DOWN 1
 #define CARD_UP 2
        atomic_t card_state;
index e0489578945dccda63d486d83e1d55b5228a2753..776692946562090527838259d780db424b9afc11 100644 (file)
@@ -3802,6 +3802,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
        struct skge_hw *hw  = pci_get_drvdata(pdev);
        int i, err, wol = 0;
 
+       if (!hw)
+               return 0;
+
        err = pci_save_state(pdev);
        if (err)
                return err;
@@ -3830,6 +3833,9 @@ static int skge_resume(struct pci_dev *pdev)
        struct skge_hw *hw  = pci_get_drvdata(pdev);
        int i, err;
 
+       if (!hw)
+               return 0;
+
        err = pci_set_power_state(pdev, PCI_D0);
        if (err)
                goto out;
@@ -3868,6 +3874,9 @@ static void skge_shutdown(struct pci_dev *pdev)
        struct skge_hw *hw  = pci_get_drvdata(pdev);
        int i, wol = 0;
 
+       if (!hw)
+               return;
+
        for (i = 0; i < hw->ports; i++) {
                struct net_device *dev = hw->dev[i];
                struct skge_port *skge = netdev_priv(dev);
index a307310f13f5e7c6ef05fea1126fdbb3928cdabf..104e20456e6f4bc64a076380a40aae460f9333e2 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <linux/mii.h>
+#include <linux/dmi.h>
 
 #include <asm/irq.h>
 
@@ -130,7 +131,7 @@ static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
-       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+//     { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
        { 0 }
 };
 
@@ -150,6 +151,8 @@ static const char *yukon2_name[] = {
        "FE",           /* 0xb7 */
 };
 
+static int dmi_blacklisted;
+
 /* Access to external PHY */
 static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
 {
@@ -2531,6 +2534,17 @@ static int __devinit sky2_init(struct sky2_hw *hw)
                return -EOPNOTSUPP;
        }
 
+
+       /* Some Gigabyte motherboards have 88e8056 but cause problems
+        * There is some unresolved hardware related problem that causes
+        * descriptor errors and receive data corruption.
+        */
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) {
+               dev_err(&hw->pdev->dev,
+                       "88E8056 on this motherboard not supported\n");
+               return -EOPNOTSUPP;
+       }
+
        hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
        hw->ports = 1;
        t8 = sky2_read8(hw, B2_Y2_HW_RES);
@@ -3578,17 +3592,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
                goto err_out;
        }
 
-       /* Some Gigabyte motherboards have 88e8056 but cause problems
-        * There is some unresolved hardware related problem that causes
-        * descriptor errors and receive data corruption.
-        */
-       if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
-           pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
-               dev_err(&pdev->dev,
-                       "88E8056 on Gigabyte motherboards not supported\n");
-               goto err_out_disable;
-       }
-
        err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
                dev_err(&pdev->dev, "cannot obtain PCI resources\n");
@@ -3732,6 +3735,7 @@ err_out_free_regions:
 err_out_disable:
        pci_disable_device(pdev);
 err_out:
+       pci_set_drvdata(pdev, NULL);
        return err;
 }
 
@@ -3784,6 +3788,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
        struct sky2_hw *hw = pci_get_drvdata(pdev);
        int i, wol = 0;
 
+       if (!hw)
+               return 0;
+
        del_timer_sync(&hw->idle_timer);
        netif_poll_disable(hw->dev[0]);
 
@@ -3815,6 +3822,9 @@ static int sky2_resume(struct pci_dev *pdev)
        struct sky2_hw *hw = pci_get_drvdata(pdev);
        int i, err;
 
+       if (!hw)
+               return 0;
+
        err = pci_set_power_state(pdev, PCI_D0);
        if (err)
                goto out;
@@ -3861,6 +3871,9 @@ static void sky2_shutdown(struct pci_dev *pdev)
        struct sky2_hw *hw = pci_get_drvdata(pdev);
        int i, wol = 0;
 
+       if (!hw)
+               return;
+
        del_timer_sync(&hw->idle_timer);
        netif_poll_disable(hw->dev[0]);
 
@@ -3897,8 +3910,24 @@ static struct pci_driver sky2_driver = {
        .shutdown = sky2_shutdown,
 };
 
+static struct dmi_system_id __initdata broken_dmi_table[] = {
+       {
+               .ident = "Gigabyte 965P-S3",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),
+
+               },
+       },
+       { }
+};
+
 static int __init sky2_init_module(void)
 {
+       /* Look for sick motherboards */
+       if (dmi_check_system(broken_dmi_table))
+               dmi_blacklisted = 1;
+
        return pci_register_driver(&sky2_driver);
 }
 
index c15e97253ede41611153c4fdbd12b3376165f631..108adbf5b5ebf395983222c50162e4a347ea5885 100644 (file)
@@ -175,12 +175,10 @@ spider_net_setup_aneg(struct spider_net_card *card)
 {
        struct mii_phy *phy = &card->phy;
        u32 advertise = 0;
-       u16 bmcr, bmsr, stat1000, estat;
+       u16 bmsr, estat;
 
-       bmcr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR);
-       bmsr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
-       stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000);
-       estat    = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
+       bmsr  = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+       estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
 
        if (bmsr & BMSR_10HALF)
                advertise |= ADVERTISED_10baseT_Half;
index 8897f538a7c788f6c2b7a7a65f7f7414e12ab6be..4fc8681bc110696305b6acc63da9ec6afdcc5e58 100644 (file)
@@ -2,10 +2,7 @@
 # wan devices configuration
 #
 
-menu "Wan interfaces"
-       depends on NETDEVICES
-
-config WAN
+menuconfig WAN
        bool "Wan interfaces support"
        ---help---
          Wide Area Networks (WANs), such as X.25, Frame Relay and leased
@@ -23,10 +20,12 @@ config WAN
 
          If unsure, say N.
 
+if WAN
+
 # There is no way to detect a comtrol sv11 - force it modular for now.
 config HOSTESS_SV11
        tristate "Comtrol Hostess SV-11 support"
-       depends on WAN && ISA && m && ISA_DMA_API && INET
+       depends on ISA && m && ISA_DMA_API && INET
        help
          Driver for Comtrol Hostess SV-11 network card which
          operates on low speed synchronous serial links at up to
@@ -38,7 +37,7 @@ config HOSTESS_SV11
 # The COSA/SRP driver has not been tested as non-modular yet.
 config COSA
        tristate "COSA/SRP sync serial boards support"
-       depends on WAN && ISA && m && ISA_DMA_API
+       depends on ISA && m && ISA_DMA_API
        ---help---
          Driver for COSA and SRP synchronous serial boards.
 
@@ -62,7 +61,7 @@ config COSA
 #
 config LANMEDIA
        tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
-       depends on WAN && PCI
+       depends on PCI
        ---help---
          Driver for the following Lan Media family of serial boards:
 
@@ -89,7 +88,7 @@ config LANMEDIA
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
        tristate "Sealevel Systems 4021 support"
-       depends on WAN && ISA && m && ISA_DMA_API && INET
+       depends on ISA && m && ISA_DMA_API && INET
        help
          This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
@@ -99,7 +98,6 @@ config SEALEVEL_4021
 # Generic HDLC
 config HDLC
        tristate "Generic HDLC layer"
-       depends on WAN
        help
          Say Y to this option if your Linux box contains a WAN (Wide Area
          Network) card supported by this driver and you are planning to
@@ -167,7 +165,7 @@ config HDLC_X25
          If unsure, say N.
 
 comment "X.25/LAPB support is disabled"
-       depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
+       depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
 
 config PCI200SYN
        tristate "Goramo PCI200SYN support"
@@ -230,10 +228,10 @@ config PC300_MLPPP
          Multilink PPP over the PC300 synchronous communication boards.
 
 comment "Cyclades-PC300 MLPPP support is disabled."
-       depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+       depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
 
 comment "Refer to the file README.mlppp, provided by PC300 package."
-       depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+       depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
 
 config PC300TOO
        tristate "Cyclades PC300 RSV/X21 alternative support"
@@ -338,7 +336,6 @@ config DSCC4_PCI_RST
 
 config DLCI
        tristate "Frame Relay DLCI support"
-       depends on WAN
        ---help---
          Support for the Frame Relay protocol.
 
@@ -385,7 +382,7 @@ config SDLA
 # Wan router core.
 config WAN_ROUTER_DRIVERS
        tristate "WAN router drivers"
-       depends on WAN && WAN_ROUTER
+       depends on WAN_ROUTER
        ---help---
          Connect LAN to WAN via Linux box.
 
@@ -440,7 +437,7 @@ config CYCLOMX_X25
 # X.25 network drivers
 config LAPBETHER
        tristate "LAPB over Ethernet driver (EXPERIMENTAL)"
-       depends on WAN && LAPB && X25
+       depends on LAPB && X25
        ---help---
          Driver for a pseudo device (typically called /dev/lapb0) which allows
          you to open an LAPB point-to-point connection to some other computer
@@ -456,7 +453,7 @@ config LAPBETHER
 
 config X25_ASY
        tristate "X.25 async driver (EXPERIMENTAL)"
-       depends on WAN && LAPB && X25
+       depends on LAPB && X25
        ---help---
          Send and receive X.25 frames over regular asynchronous serial
          lines such as telephone lines equipped with ordinary modems.
@@ -471,7 +468,7 @@ config X25_ASY
 
 config SBNI
        tristate "Granch SBNI12 Leased Line adapter support"
-       depends on WAN && X86
+       depends on X86
        ---help---
          Driver for ISA SBNI12-xx cards which are low cost alternatives to
          leased line modems.
@@ -497,5 +494,4 @@ config SBNI_MULTILINE
 
          If unsure, say N.
 
-endmenu
-
+endif # WAN
index 19c935071d8ede8dd08aa805f51b10cc5945805f..56a8ea1fbf041a6c24d8baea4efd298c089bb248 100644 (file)
@@ -1,5 +1,3 @@
-# EXTRA_CFLAGS += -Wpacked
-
 usb8xxx-objs := main.o fw.o wext.o \
                rx.o tx.o cmd.o           \
                cmdresp.o scan.o          \
@@ -7,13 +5,6 @@ usb8xxx-objs := main.o fw.o wext.o \
                ioctl.o debugfs.o         \
                ethtool.o assoc.o
 
-ifeq ($(CONFIG_LIBERTAS_USB_DEBUG), y)
-EXTRA_CFLAGS += -DDEBUG -DPROC_DEBUG
-endif
-
-
-# This is needed to support the newer boot2 bootloader (v >= 3104)
-EXTRA_CFLAGS += -DSUPPORT_BOOT_COMMAND
 usb8xxx-objs += if_bootcmd.o
 usb8xxx-objs += if_usb.o
 
index 688da4c784b10cc6baaa200364bfe925de5e6d8d..378577200b56c5f3e81fe849c1c8d44aecb81723 100644 (file)
@@ -40,64 +40,11 @@ NAME
 SYNOPSIS
        iwpriv <ethX> <command> [sub-command] ...
 
-       iwpriv ethX version
-       iwpriv ethX scantype [sub-command]
-       iwpriv ethX getSNR <n>
-       iwpriv ethX getNF <n>
-       iwpriv ethX getRSSI <n>
-       iwpriv ethX setrxant <n>
-       iwpriv ethX getrxant
-       iwpriv ethX settxant <n>
-       iwpriv ethX gettxant
-       iwpriv ethX authalgs <n>
-       iwpriv ethX pre-TBTT <n>
-       iwpriv ethX 8021xauthalgs <n>
-       iwpriv ethX encryptionmode <n>
        iwpriv ethX setregioncode <n>
        iwpriv ethX getregioncode
-       iwpriv ethX setbcnavg <n>
-       iwpriv ethX getbcnavg
-       iwpriv ethX setdataavg <n>
-       iwpriv ethX setlisteninter <n>
-       iwpriv ethX getlisteninter
-       iwpriv ethX setmultipledtim <n>
-       iwpriv ethX getmultipledtim
-       iwpriv ethX atimwindow <n>
-       iwpriv ethX deauth
-       iwpriv ethX adhocstop
-       iwpriv ethX radioon
-       iwpriv ethX radiooff
-       iwpriv ethX reasso-on
-       iwpriv ethX reasso-off
-       iwpriv ethX scanmode  [sub-command]
-       iwpriv ethX setwpaie <n>
-       iwpriv ethX wlanidle-off
-       iwpriv ethX wlanidle-on
-       iwpriv ethX getcis
-       iwpriv ethX getlog
-       iwpriv ethX getadhocstatus
-       iwpriv ethX adhocgrate <n>
-
-Version 4 Command:
-       iwpriv ethX inactvityto <n>
-       iwpriv ethX sleeppd <n>
-       iwpriv ethX enable11d <n>
-       iwpriv ethX tpccfg <n>
-       iwpriv ethX powercfg <n>
-       iwpriv ethX setafc <n>
-       iwpriv ethX getafc
 
 Version 5 Command:
        iwpriv ethX ledgpio <n>
-       iwpriv ethX scanprobes <n>
-       iwpriv ethX lolisteninter <n>
-       iwpriv ethX rateadapt <n> <m>
-       iwpriv ethX txcontrol <n>
-       iwpriv ethX psnullinterval <n>
-       iwpriv ethX prescan <n>
-       iwpriv ethX getrxinfo
-       iwpriv ethX gettxrate
-       iwpriv ethX beaconinterval
 
 BT Commands:
        The blinding table (BT) contains a list of mac addresses that should be
@@ -150,114 +97,6 @@ DESCRIPTION
        The ethX parameter specifies the network device that is to be used to
                perform this command on. it could be eth0, eth1 etc.
 
-version
-       This is used to get the current version of the driver and the firmware.
-
-scantype
-       This command is used to set the scan type to be used by the driver in
-       the scan command. This setting will not be used while performing a scan
-       for a specific SSID, as it is always done with scan type being active.
-
-       where the sub-commands are: -
-                       active  -- to set the scan type to active
-                       passive -- to set the scan type to passive
-                       get     -- to get the scan type set in the driver
-
-getSNR
-       This command gets the average and non average value of Signal to Noise
-       Ratio of Beacon and Data.
-
-       where value is:-
-                       0       -- Beacon non-average.
-                       1       -- Beacon average.
-                       2       -- Data non-average.
-                       3       -- Data average.
-
-       If no value is given, all four values are returned in the order mentioned
-       above.
-
-       Note: This command is available only when STA is connected.
-
-getRSSI
-       This command gets the average and non average value os Receive Signal
-       Strength of Beacon and Data.
-
-       where value is:-
-                       0       -- Beacon non-average.
-                       1       -- Beacon average.
-                       2       -- Data non-average.
-                       3       -- Data average.
-
-       Note: This command is available only when STA is connected.
-
-getNF
-       This command gets the average and non average value of Noise Floor of
-       Beacon and Data.
-
-       where value is:-
-                       0       -- Beacon non-average.
-                       1       -- Beacon average.
-                       2       -- Data non-average.
-                       3       -- Data average.
-
-       Note: This command is available only when STA is connected.
-
-setrxant
-       This command is used to set the mode for Rx antenna.
-
-       The options that can be sent are:-
-                       1       -- Antenna 1.
-                       2       -- Antenna 2.
-                       0xFFFF  -- Diversity.
-
-       Usage:
-               iwpriv ethX setrxant 0x01: select Antenna 1.
-
-getrxant
-       This command is used to get the mode for Rx antenna.
-
-
-settxant
-       This command is used to set the mode for Tx antenna.
-               The options that can be sent are:-
-                       1       -- Antenna 1.
-                       2       -- Antenna 2.
-                       0xFFFF  -- Diversity.
-       Usage:
-               iwpriv ethX settxant 0x01: select Antenna 1.
-
-gettxant
-       This command is used to get the mode for Tx antenna.
-
-authalgs
-       This command is used by the WPA supplicant to set the authentication
-       algorithms in the station.
-
-8021xauthalgs
-       This command is used by the WPA supplicant to set the 8021.x authentication algorithm type
-       station.
-
-       where values can be:-
-                       1       -- None
-                       2       -- LEAP
-                       4       -- TLS
-                       8       -- TTLs
-                       16      -- MD5
-
-
-encryptionmode
-       This command is used by the WPA supplicant to set the encryption algorithm.
-
-       where values can be:-
-                       0       -- NONE
-                       1       -- WEP40
-                       2       -- TKIP
-                       3       -- CCMP
-                       4       -- WEP104
-
-pre-TBTT
-       This command is used to set pre-TBTT time period where value is in microseconds.
-
 setregioncode
        This command is used to set the region code in the station.
        where value is 'region code' for various regions like
@@ -270,114 +109,6 @@ getregioncode
        This command is used to get the region code information set in the
        station.
 
-setbcnavg
-       Set the weighting factor for calculating RSSI.
-
-getbcnavg
-       Get weighting factor for calculating RSSI.
-
-setdataavg
-       Set the weighting factor for calculating SNR.
-
-setlisteninter
-       This command is used to set the listen interval in the
-       station.
-
-       where the value ranges between 1 - 255
-
-getlisteninter
-       This command is used to get the listen interval value set in the
-       station.
-
-setmultipledtim
-       This command is used to set the multiple dtim value in the
-       station.
-               where the value is 1,2,3,4,5,0xfffe
-               0xfffe means the firmware will use listen interval in association
-               command for waking up
-
-getmultipledtim
-       This command is used to get the multiple dtim value set in the station.
-
-atimwindow
-       This command is used to set the atim value in the
-       station.
-
-       where the value ranges between 0 - 50
-
-deauth
-       This command is used to send the de-authentication to the AP with which
-       the station is associated. This command is valid only when
-       station is in Infrastructure mode.
-
-       Note: This command is available only when STA is connected.
-
-adhocstop
-       This command is used to stop beacon transmission from the station and
-       go into idle state in ad-hoc mode.
-
-       Note: This command is available only when STA is connected.
-
-radioon
-       This command is used to turn on the RF antenna.
-
-radiooff
-       This command is sued to turn off the RF antenna.
-
-scanmode
-       This command is used to set the station to scan for either IBSS
-       networks or BSS networks or both BSS and IBSS networks. This
-       command can be used with sub commands,
-
-       where the value for
-                       bss     -- Scan All the BSS networks.
-                       ibss    -- Scan All the IBSS networks.
-                       any     -- Scan both BSS and IBSS networks.
-
-
-
-setwpaie
-       This command is used by WPA supplicant to send the WPA-IE to the driver.
-
-wlanidle-off
-       This command is used to get into idle state.
-
-       Note: This command is available only when STA is connected.
-
-wlanidle-on
-       This command is used to get off the idle state.
-
-       Note: This command is available only when STA is connected.
-
-
-getlog
-       This command is used to get the 802.11 statistics available in the
-               station.
-
-       Note: This command is available only when STA is connected.
-
-getadhocstatus
-       This command is used to get the ad-hoc Network Status.
-
-       The various status codes are:
-               AdhocStarted
-               AdhocJoined
-               AdhocIdle
-               InfraMode
-               AutoUnknownMode
-
-       Note: This command is available only when STA is connected.
-
-adhocgrate
-       This command is used to enable(1) g_rate, Disable(0) g_rate
-       and request(2) the status which g_rate is disabled/enabled,
-       for Ad-hoc creator.
-
-       where value is:-
-               0       -- Disabled
-               1       -- Enabled
-               2       -- Get
-
 ledgpio
        This command is used to set/get LEDs.
 
@@ -400,253 +131,6 @@ ledgpio
        Note: LED0 is invalid
        Note: Maximum Number of LEDs are 16.
 
-inactivityto
-       This command is used by the host to set/get the inactivity timeout value,
-       which specifies when WLAN device is put to sleep.
-
-       Usage:
-               iwpriv ethX inactivityto [<timeout>]
-
-       where the parameter are:
-               timeout: timeout value in milliseconds.
-
-       Example:
-               iwpriv eth1 inactivityto
-                       "get the timeout value"
-
-               iwpriv eth1 inactivityto X
-                       "set timeout value to X ms"
-
-
-sleeppd
-       This command is used to configure the sleep period of the WLAN device.
-
-       Usage:
-               iwpriv ethX sleeppd [<sleep period>]
-
-       where the parameter are:
-               Period: sleep period in milliseconds. Range 10~60.
-
-       Example:
-               iwpriv eth1 sleeppd 10
-                       "set period as 10 ms"
-               iwpriv eth1 sleeppd
-                       "get the sleep period configuration"
-
-enable11d
-       This command is used to control 11d
-       where value is:-
-               1       -- Enabled
-               0       -- Disabled
-               2       -- Get
-
-
-
-
-tpccfg
-       Enables or disables automatic transmit power control.
-
-       The first parameter turns this feature on (1) or off (0).  When turning
-       on, the user must also supply four more parameters in the following
-       order:
-               -UseSNR (Use SNR (in addition to PER) for TPC algorithm),
-               -P0 (P0 power level for TPC),
-               -P1 (P1 power level for TPC),
-               -P2 (P2 power level for TPC).
-
-       Usage:
-               iwpriv ethX tpccfg: Get current configuration
-               iwpriv ethX tpccfg 0: disable auto TPC
-               iwpriv ethX tpccfg 0x01 0x00 0x05 0x0a 0x0d: enable auto TPC; do not use SNR;
-                                                            P0=0x05; P1=0x0a; P2=0x0d;
-               iwpriv ethX tpccfg 0x01 0x01 0x05 0x0a 0x0d: enable auto TPC; use SNR;
-                                                            P0=0x05; P1=0x0a; P2=0x0d.
-
-powercfg
-       Enables or disables power adaptation.
-
-       The first parameter turns this feature on (1) or off (0).  When turning
-       on, the user must also supply three more parameters in the following
-       order:
-               -P0 (P0 power level for Power Adaptation),
-               -P1 (P1 power level for Power Adaptation),
-               -P2 (P2 power level for Power Adaptation).
-
-       Usage:
-               iwpriv ethX powercfg: Get current configuration
-               iwpriv ethX powercfg 0: disable power adaptation
-               iwpriv ethX powercfg 1 0x0d 0x0f 0x12: enable power adaptation;
-                                                      P0=0x0d; P1=0x0f; P2=0x12.
-
-getafc
-       This command returns automatic frequency control parameters.  It returns
-       three integers:
-               -P0: automatic is on (1), or off (0),
-               -P1: current timing offset in PPM (part per million), and
-               -P2: current frequency offset in PPM.
-
-setafc
-       Set automatic frequency control options.
-
-       The first parameter turns automatic on (1) or off (0).
-       The user must supply two more parameters in either case, in the following
-  order:
-
-  When auto is on:
-
-               -P0 (automatic adjustment frequency threshold in PPM),
-               -P1 (automatic adjustment period in beacon period),
-
-  When auto is off:
-
-               -P0 (manual adjustment timing offset in PPM), and
-               -P1 (manual adjustment frequency offset in PPM).
-
-       Usage:
-               iwpriv ethX setafc 0 10 10: manual adjustment, both timing and frequcncy
-    offset are 10 PPM.
-
-               iwpriv ethX setafc 1 10 10 enable afc, automatic adjustment,
-    frequency threshold 10 PPM, for every 10 beacon periods.
-
-
-
-scanprobes
-       This command sets number of probe requests per channel.
-
-       Usage:
-               iwpriv ethX scanprobes 3 (set scan probes to 3)
-               iwpriv ethX scanprobes   (get scan probes)
-
-lolisteninter
-       This command sets the value of listen interval.
-
-       Usage:
-       iwpriv ethX lolisteninter 234 (set the lolisteninter to 234)
-       iwpriv ethX lolisteninter     (get the lolisteninter value)
-
-rateadapt
-       This command sets the data rates bitmap.
-       Where <n>
-               0: Disable auto rate adapt
-               1: Enable auto rate adapt
-
-             <m>
-                data rate bitmap
-                       Bit     Data rate
-                       0       1 Mbps
-                       1       2 Mbps
-                       2       5.5 Mbps
-                       3       11 Mbps
-                       4       Reserved
-                       5       6 Mbps
-                       6       9 Mbps
-                       7       12 Mbps
-                       8       18 Mbps
-                       9       24 Mbps
-                       10      36 Mbps
-                       11      48 Mbps
-                       12      54 Mbps
-                       12-15   Reserved
-
-       Usage:
-       iwpriv ethX rateadapt
-                       read the currect data rate setting
-       iwpriv ethX rateadapt 1 0x07
-                       enable auto data rate adapt and
-                       data rates are 1Mbps, 2Mbsp and 5.5Mbps
-
-
-txcontrol
-       This command is used to set the Tx rate, ack policy, and retry limit on a per packet basis.
-
-       Where value <n> is:
-           if bit[4] == 1:
-               bit[3:0]        -- 0   1   2   3   4   5   6   7   8   9   10   11   12   13-16
-               Data Rate(Mbps) -- 1   2   5.5 11  Rsv 6   9   12  18  24  36   48   54   Rsv
-
-           bit[12:8]
-               if bit[12] == 1, bit[11:8] specifies the Tx retry limit.
-
-           bit[14:13] specifies per packet ack policy:
-               bit[14:13]
-                    1  0       use immediate ack policy for this packet
-                    1  1       use no ack policy for this packet
-                    0  x       use the per-packet ack policy setting
-
-       Usage:
-       iwpriv ethX txcontrol 0x7513
-                       Use no-ack policy, 5 retires for Tx, 11Mbps rate
-
-
-
-psnullinterval
-       This command is used to set/request NULL package interval for Power Save
-       under infrastructure mode.
-
-       where value is:-
-               -1      -- Disabled
-               n>0     -- Set interval as n (seconds)
-
-prescan
-       This command is used to enable (1)/disable(0) auto prescan before assoicate to the ap
-
-       where value is:-
-               0       -- Disabled
-               1       -- Enabled
-               2       -- Get
-
-getrxinfo
-       This command gets non average value of Signal to Noise Ratio of Data and rate index.
-
-       The following table shows RateIndex and Rate
-
-                    RateIndex  Data rate
-                       0       1 Mbps
-                       1       2 Mbps
-                       2       5.5 Mbps
-                       3       11 Mbps
-                       4       Reserved
-                       5       6 Mbps
-                       6       9 Mbps
-                       7       12 Mbps
-                       8       18 Mbps
-                       9       24 Mbps
-                       10      36 Mbps
-                       11      48 Mbps
-                       12      54 Mbps
-                       13-15   Reserved
-
-gettxrate
-       This command gets current Tx rate index of the first packet associated with Rate Adaptation.
-
-       The following table shows RateIndex and Rate
-
-                    RateIndex  Data rate
-                       0       1 Mbps
-                       1       2 Mbps
-                       2       5.5 Mbps
-                       3       11 Mbps
-                       4       Reserved
-                       5       6 Mbps
-                       6       9 Mbps
-                       7       12 Mbps
-                       8       18 Mbps
-                       9       24 Mbps
-                       10      36 Mbps
-                       11      48 Mbps
-                       12      54 Mbps
-                       13-15   Reserved
-
-bcninterval
-       This command is used to sets beacon interval in adhoc mode when an argument is given, and gets current adhoc
-       beacon interval when no argument is given. The valid beacon interval is between 20 - 1000,
-       default beacon interval is 100.
-
-       Usage:
-               iwpriv ethX bcninterval 100  (set adhoc beacon interval to 100)
-               iwpriv ethX bcninterval      (get adhoc beacon interval)
-
 fwt_add
        This command is used to insert an entry into the FWT table. The list of
        parameters must follow the following structure:
index b55c7f57aca8d34a4fc7c333e0d2ddf522f9752d..c260bd1b3d46667df8cd32f2beb3fd2a06a59eb0 100644 (file)
@@ -23,13 +23,13 @@ static int assoc_helper_essid(wlan_private *priv,
        ENTER();
 
        lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
-       if (assoc_req->mode == wlan802_11infrastructure) {
+       if (assoc_req->mode == IW_MODE_INFRA) {
                if (adapter->prescan) {
                        libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
                }
 
                i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
-                               NULL, wlan802_11infrastructure);
+                               NULL, IW_MODE_INFRA);
                if (i >= 0) {
                        lbs_pr_debug(1,
                               "SSID found in scan list ... associating...\n");
@@ -44,7 +44,7 @@ static int assoc_helper_essid(wlan_private *priv,
                        lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
                                assoc_req->ssid.ssid);
                }
-       } else if (assoc_req->mode == wlan802_11ibss) {
+       } else if (assoc_req->mode == IW_MODE_ADHOC) {
                /* Scan for the network, do not save previous results.  Stale
                 *   scan data will cause us to join a non-existant adhoc network
                 */
@@ -52,7 +52,7 @@ static int assoc_helper_essid(wlan_private *priv,
 
                /* Search for the requested SSID in the scan table */
                i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
-                               wlan802_11ibss);
+                               IW_MODE_ADHOC);
                if (i >= 0) {
                        lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
                        libertas_join_adhoc_network(priv, &adapter->scantable[i]);
@@ -90,10 +90,10 @@ static int assoc_helper_bssid(wlan_private *priv,
                goto out;
        }
 
-       if (assoc_req->mode == wlan802_11infrastructure) {
+       if (assoc_req->mode == IW_MODE_INFRA) {
                ret = wlan_associate(priv, &adapter->scantable[i]);
                lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
-       } else if (assoc_req->mode == wlan802_11ibss) {
+       } else if (assoc_req->mode == IW_MODE_ADHOC) {
                libertas_join_adhoc_network(priv, &adapter->scantable[i]);
        }
        memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
@@ -142,23 +142,23 @@ static int assoc_helper_mode(wlan_private *priv,
 
        ENTER();
 
-       if (assoc_req->mode == adapter->inframode) {
+       if (assoc_req->mode == adapter->mode) {
                LEAVE();
                return 0;
        }
 
-       if (assoc_req->mode == wlan802_11infrastructure) {
+       if (assoc_req->mode == IW_MODE_INFRA) {
                if (adapter->psstate != PS_STATE_FULL_POWER)
                        libertas_ps_wakeup(priv, cmd_option_waitforrsp);
                adapter->psmode = wlan802_11powermodecam;
        }
 
-       adapter->inframode = assoc_req->mode;
+       adapter->mode = assoc_req->mode;
        ret = libertas_prepare_and_send_command(priv,
                                    cmd_802_11_snmp_mib,
                                    0, cmd_option_waitforrsp,
                                    OID_802_11_INFRASTRUCTURE_MODE,
-                                   (void *) assoc_req->mode);
+                                   (void *) (size_t) assoc_req->mode);
 
        LEAVE();
        return ret;
@@ -196,7 +196,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
                goto out;
 
        /* enable/disable the MAC's WEP packet filter */
-       if (assoc_req->secinfo.WEPstatus == wlan802_11WEPenabled)
+       if (assoc_req->secinfo.wep_enabled)
                adapter->currentpacketfilter |= cmd_act_mac_wep_enable;
        else
                adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable;
@@ -300,8 +300,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
        }
 
        if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
-               if (adapter->secinfo.authmode !=
-                   assoc_req->secinfo.authmode) {
+               if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
                        lbs_pr_debug(1, "Deauthenticating due to updated security "
                                "info in configuration request.\n");
                        return 1;
@@ -316,7 +315,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
 
        /* FIXME: deal with 'auto' mode somehow */
        if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
-               if (assoc_req->mode != wlan802_11infrastructure)
+               if (assoc_req->mode != IW_MODE_INFRA)
                        return 1;
        }
 
@@ -333,12 +332,12 @@ static int should_stop_adhoc(wlan_adapter *adapter,
        if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
                return 1;
        if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
-                       sizeof(struct WLAN_802_11_SSID)))
+                       adapter->curbssparams.ssid.ssidlength))
                return 1;
 
        /* FIXME: deal with 'auto' mode somehow */
        if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
-               if (assoc_req->mode != wlan802_11ibss)
+               if (assoc_req->mode != IW_MODE_ADHOC)
                        return 1;
        }
 
@@ -382,7 +381,7 @@ void wlan_association_worker(struct work_struct *work)
        }
 
        if (find_any_ssid) {
-               enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
+               u8 new_mode;
 
                ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
                                assoc_req->mode, &new_mode);
@@ -393,7 +392,7 @@ void wlan_association_worker(struct work_struct *work)
                }
 
                /* Ensure we switch to the mode of the AP */
-               if (assoc_req->mode == wlan802_11autounknown) {
+               if (assoc_req->mode == IW_MODE_AUTO) {
                        set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
                        assoc_req->mode = new_mode;
                }
@@ -403,7 +402,7 @@ void wlan_association_worker(struct work_struct *work)
         * Check if the attributes being changing require deauthentication
         * from the currently associated infrastructure access point.
         */
-       if (adapter->inframode == wlan802_11infrastructure) {
+       if (adapter->mode == IW_MODE_INFRA) {
                if (should_deauth_infrastructure(adapter, assoc_req)) {
                        ret = libertas_send_deauthentication(priv);
                        if (ret) {
@@ -412,7 +411,7 @@ void wlan_association_worker(struct work_struct *work)
                                        ret);
                        }
                }
-       } else if (adapter->inframode == wlan802_11ibss) {
+       } else if (adapter->mode == IW_MODE_ADHOC) {
                if (should_stop_adhoc(adapter, assoc_req)) {
                        ret = libertas_stop_adhoc_network(priv);
                        if (ret) {
@@ -543,7 +542,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
                assoc_req->channel = adapter->curbssparams.channel;
 
        if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
-               assoc_req->mode = adapter->inframode;
+               assoc_req->mode = adapter->mode;
 
        if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
                memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
index bfdac58b5c06369b41d92db2219396e519dc75bb..de9cb46a70fffaa726879cc44affb5a3144a6575 100644 (file)
@@ -381,15 +381,16 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
        switch (cmd_oid) {
        case OID_802_11_INFRASTRUCTURE_MODE:
        {
-               enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode =
-                       (enum WLAN_802_11_NETWORK_INFRASTRUCTURE) pdata_buf;
+               u8 mode = (u8) (size_t) pdata_buf;
                pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
                pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i);
                pSNMPMIB->bufsize = sizeof(u8);
-               if (mode == wlan802_11infrastructure)
-                       ucTemp = SNMP_MIB_VALUE_INFRA;
-               else
+               if (mode == IW_MODE_ADHOC) {
                        ucTemp = SNMP_MIB_VALUE_ADHOC;
+               } else {
+                       /* Infra and Auto modes */
+                       ucTemp = SNMP_MIB_VALUE_INFRA;
+               }
 
                memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
 
@@ -947,8 +948,8 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
 
        spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
-       lbs_pr_debug(1, "QUEUE_CMD: Inserted node=0x%x, cmd=0x%x in cmdpendingq\n",
-              (u32) cmdnode,
+       lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
+              cmdnode,
               ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
 
 done:
@@ -976,8 +977,8 @@ static int DownloadcommandToStation(wlan_private * priv,
        ENTER();
 
        if (!adapter || !cmdnode) {
-               lbs_pr_debug(1, "DNLD_CMD: adapter = %#x, cmdnode = %#x\n",
-                      (int)adapter, (int)cmdnode);
+               lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n",
+                      adapter, cmdnode);
                if (cmdnode) {
                        spin_lock_irqsave(&adapter->driver_lock, flags);
                        __libertas_cleanup_and_insert_cmd(priv, cmdnode);
@@ -1174,8 +1175,8 @@ int libertas_prepare_and_send_command(wlan_private * priv,
 
        cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
 
-       lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr =0x%x, command=0x%X\n",
-              (u32) cmdptr, cmd_no);
+       lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
+              cmdptr, cmd_no);
 
        if (!cmdptr) {
                lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
index cdb012c7e9cfcf1c2190b52d2a76742f1814b9c4..c86454034b5839c64dd9a40f92d07c8c928b6aac 100644 (file)
@@ -72,8 +72,6 @@ void libertas_mac_event_disconnected(wlan_private * priv)
        adapter->secinfo.WPAenabled = 0;
        adapter->secinfo.WPA2enabled = 0;
        adapter->wpa_ie_len = 0;
-       adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
-       adapter->secinfo.Encryptionmode = CIPHER_NONE;
 
        adapter->connect_status = libertas_disconnected;
 
@@ -811,7 +809,7 @@ int libertas_process_rx_command(wlan_private * priv)
                if (result) {
                        lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
                               resp->result);
-                       if (adapter->inframode == wlan802_11ibss) {
+                       if (adapter->mode == IW_MODE_ADHOC) {
                                /*
                                 * We should not re-try enter-ps command in
                                 * ad-hoc mode. It takes place in
index 51dfd202f5588b79e71f025c54c859c2d5ad7c45..7d7bc5e86a5663610e8d31fc08c7f9020d9aac63 100644 (file)
@@ -7,6 +7,7 @@
 #include "dev.h"
 #include "decl.h"
 #include "host.h"
+#include "debugfs.h"
 
 static struct dentry *libertas_dir = NULL;
 static char *szStates[] = {
@@ -276,7 +277,7 @@ static void libertas_parse_ssid(char *buf, size_t count,
        if (!end)
                end = buf + count - 1;
 
-       size = min(IW_ESSID_MAX_SIZE, end - hold);
+       size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
        strncpy(scan_cfg->specificSSID, hold, size);
 
        return;
@@ -1648,7 +1649,7 @@ struct libertas_debugfs_files {
        struct file_operations fops;
 };
 
-struct libertas_debugfs_files debugfs_files[] = {
+static struct libertas_debugfs_files debugfs_files[] = {
        { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
        { "getscantable", 0444, FOPS(libertas_getscantable,
                                        write_file_dummy), },
@@ -1658,7 +1659,7 @@ struct libertas_debugfs_files debugfs_files[] = {
        { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
 };
 
-struct libertas_debugfs_files debugfs_events_files[] = {
+static struct libertas_debugfs_files debugfs_events_files[] = {
        {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
                                libertas_lowrssi_write), },
        {"low_snr", 0644, FOPS(libertas_lowsnr_read,
@@ -1673,7 +1674,7 @@ struct libertas_debugfs_files debugfs_events_files[] = {
                                libertas_highsnr_write), },
 };
 
-struct libertas_debugfs_files debugfs_regs_files[] = {
+static struct libertas_debugfs_files debugfs_regs_files[] = {
        {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
        {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
        {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
@@ -1778,7 +1779,7 @@ void libertas_debugfs_remove_one(wlan_private *priv)
 struct debug_data {
        char name[32];
        u32 size;
-       u32 addr;
+       size_t addr;
 };
 
 /* To debug any member of wlan_adapter, simply add one line here.
@@ -1825,6 +1826,8 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
                        val = *((u16 *) d[i].addr);
                else if (d[i].size == 4)
                        val = *((u32 *) d[i].addr);
+               else if (d[i].size == 8)
+                       val = *((u64 *) d[i].addr);
 
                pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
        }
@@ -1844,7 +1847,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
  *  @param data    data to write
  *  @return       number of data
  */
-static int wlan_debugfs_write(struct file *f, const char __user *buf,
+static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
                            size_t cnt, loff_t *ppos)
 {
        int r, i;
@@ -1886,12 +1889,14 @@ static int wlan_debugfs_write(struct file *f, const char __user *buf,
                                *((u16 *) d[i].addr) = (u16) r;
                        else if (d[i].size == 4)
                                *((u32 *) d[i].addr) = (u32) r;
+                       else if (d[i].size == 8)
+                               *((u64 *) d[i].addr) = (u64) r;
                        break;
                } while (1);
        }
        kfree(pdata);
 
-       return cnt;
+       return (ssize_t)cnt;
 }
 
 static struct file_operations libertas_debug_fops = {
@@ -1916,20 +1921,10 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev)
                return;
 
        for (i = 0; i < num_of_items; i++)
-               items[i].addr += (u32) priv->adapter;
+               items[i].addr += (size_t) priv->adapter;
 
        priv->debugfs_debug = debugfs_create_file("debug", 0644,
                                                  priv->debugfs_dir, &items[0],
                                                  &libertas_debug_fops);
 }
 
-/**
- *  @brief remove proc file
- *
- *  @param priv           pointer wlan_private
- *  @return       N/A
- */
-void libertas_debug_remove(wlan_private * priv)
-{
-       debugfs_remove(priv->debugfs_debug);
-}
index fb1478c1b87d3ae99c718ae5bb72c300228e2280..80dd9ea19c8e4b7ea2faa8c4cbf5874acc77e0a6 100644 (file)
@@ -9,6 +9,11 @@
 
 extern unsigned int libertas_debug;
 
+#ifdef CONFIG_LIBERTAS_DEBUG
+#define DEBUG
+#define PROC_DEBUG
+#endif
+
 #define DRV_NAME               "usb8xxx"
 
 #define lbs_pr_info(format, args...) \
@@ -223,31 +228,6 @@ enum SNRNF_DATA {
        MAX_TYPE_AVG
 };
 
-/** WLAN_802_11_AUTH_ALG*/
-enum WLAN_802_11_AUTH_ALG {
-       AUTH_ALG_OPEN_SYSTEM = 1,
-       AUTH_ALG_SHARED_KEY = 2,
-       AUTH_ALG_NETWORK_EAP = 8,
-};
-
-/** WLAN_802_1X_AUTH_ALG */
-enum WLAN_802_1X_AUTH_ALG {
-       WLAN_1X_AUTH_ALG_NONE = 1,
-       WLAN_1X_AUTH_ALG_LEAP = 2,
-       WLAN_1X_AUTH_ALG_TLS = 4,
-       WLAN_1X_AUTH_ALG_TTLS = 8,
-       WLAN_1X_AUTH_ALG_MD5 = 16,
-};
-
-/** WLAN_802_11_ENCRYPTION_MODE */
-enum WLAN_802_11_ENCRYPTION_MODE {
-       CIPHER_NONE,
-       CIPHER_WEP40,
-       CIPHER_TKIP,
-       CIPHER_CCMP,
-       CIPHER_WEP104,
-};
-
 /** WLAN_802_11_POWER_MODE */
 enum WLAN_802_11_POWER_MODE {
        wlan802_11powermodecam,
@@ -292,28 +272,6 @@ enum mv_ms_type {
        MVMS_EVENT
 };
 
-/** WLAN_802_11_NETWORK_INFRASTRUCTURE */
-enum WLAN_802_11_NETWORK_INFRASTRUCTURE {
-       wlan802_11ibss,
-       wlan802_11infrastructure,
-       wlan802_11autounknown,
-       /*defined as upper bound */
-       wlan802_11infrastructuremax
-};
-
-/** WLAN_802_11_AUTHENTICATION_MODE */
-enum WLAN_802_11_AUTHENTICATION_MODE {
-       wlan802_11authmodeopen = 0x00,
-       wlan802_11authmodeshared = 0x01,
-       wlan802_11authmodenetworkEAP = 0x80,
-};
-
-/** WLAN_802_11_WEP_STATUS */
-enum WLAN_802_11_WEP_STATUS {
-       wlan802_11WEPenabled,
-       wlan802_11WEPdisabled,
-};
-
 /** SNMP_MIB_INDEX_e */
 enum SNMP_MIB_INDEX_e {
        desired_bsstype_i = 0,
index b1f876f9693bf93fc24f222b59f97bdd06677be1..e8b9020f9bd69676654177a54944cbd4e1fb5751 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
+#include <net/ieee80211.h>
 
 #include "defs.h"
 #include "scan.h"
@@ -56,10 +57,8 @@ struct region_channel {
 struct wlan_802_11_security {
        u8 WPAenabled;
        u8 WPA2enabled;
-       enum WLAN_802_11_WEP_STATUS WEPstatus;
-       enum WLAN_802_11_AUTHENTICATION_MODE authmode;
-       enum WLAN_802_1X_AUTH_ALG auth1xalg;
-       enum WLAN_802_11_ENCRYPTION_MODE Encryptionmode;
+       u8 wep_enabled;
+       u8 auth_mode;
 };
 
 /** Current Basic Service Set State Structure */
@@ -184,7 +183,7 @@ struct assoc_request {
 
        struct WLAN_802_11_SSID ssid;
        u8 channel;
-       enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode;
+       u8 mode;
        u8 bssid[ETH_ALEN];
 
        /** WEP keys */
@@ -198,7 +197,6 @@ struct assoc_request {
        struct wlan_802_11_security secinfo;
 
        /** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
        u8 wpa_ie[MAX_WPA_IE_LEN];
        u8 wpa_ie_len;
 };
@@ -254,7 +252,8 @@ struct _wlan_adapter {
        /** current ssid/bssid related parameters*/
        struct current_bss_params curbssparams;
 
-       enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+       /* IW_MODE_* */
+       u8 mode;
 
        struct bss_descriptor *pattemptedbssdesc;
 
@@ -339,7 +338,6 @@ struct _wlan_adapter {
        struct WLAN_802_11_KEY wpa_unicast_key;
 
        /** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
        u8 wpa_ie[MAX_WPA_IE_LEN];
        u8 wpa_ie_len;
 
index b194a457079162a45da00ac3bfbbe518bcc3dc90..441123c85e62ce0a3d68ec0f0db26414966683a3 100644 (file)
@@ -194,16 +194,13 @@ static void wlan_init_adapter(wlan_private * priv)
        adapter->scanmode = cmd_bss_type_any;
 
        /* 802.11 specific */
-       adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
+       adapter->secinfo.wep_enabled = 0;
        for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
             i++)
                memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
        adapter->wep_tx_keyidx = 0;
-       adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
-       adapter->secinfo.authmode = wlan802_11authmodeopen;
-       adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
-       adapter->secinfo.Encryptionmode = CIPHER_NONE;
-       adapter->inframode = wlan802_11infrastructure;
+       adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
+       adapter->mode = IW_MODE_INFRA;
 
        adapter->assoc_req = NULL;
 
index 695fb6a66ffed2dd03949d8105a6437f70d60c44..ae6f72a6cdf396d5946e5ff1de1863c18a6d0380 100644 (file)
@@ -388,7 +388,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
        usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
                          usb_rcvbulkpipe(cardp->udev,
                                          cardp->bulk_in_endpointAddr),
-                         skb->tail + IPFIELD_ALIGN_OFFSET,
+                         (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
                          MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
                          rinfo);
 
@@ -626,6 +626,7 @@ static void if_usb_receive(struct urb *urb)
                            cardp->usb_event_cause);
                if (cardp->usb_event_cause & 0xffff0000) {
                        libertas_send_tx_feedback(priv);
+                       spin_unlock(&priv->adapter->driver_lock);
                        break;
                }
                cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
@@ -775,7 +776,6 @@ restart:
                return -1;
        }
 
-#ifdef SUPPORT_BOOT_COMMAND
        cardp->bootcmdresp = 0;
        do {
                int j = 0;
@@ -796,7 +796,6 @@ restart:
                }
                return -1;
        }
-#endif
 
        i = 0;
        priv->adapter->fw_ready = 0;
index 785116720bc6c884b5c15a14e3545fe1739e63a4..170dfe6809f5eb1cd9e4ff552dc6edad0651188d 100644 (file)
@@ -12,7 +12,6 @@
 #define USB8388_VID_2  0x05a3
 #define USB8388_PID_2  0x8388
 
-#ifdef SUPPORT_BOOT_COMMAND
 #define BOOT_CMD_FW_BY_USB     0x01
 #define BOOT_CMD_FW_IN_EEPROM  0x02
 #define BOOT_CMD_UPDATE_BOOT2  0x03
@@ -36,7 +35,6 @@ struct bootcmdrespStr
        u8  u8result;
        u8  au8dumy[2];
 };
-#endif /* SUPPORT_BOOT_COMMAND */
 
 /* read callback private data */
 struct read_cb_info {
index 82b39642423a3ad45d2352e85d97588fc085e985..a8f76c35899240837ba6aadb47f696a14a52d7b2 100644 (file)
 
 #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
 
-static int setrxantenna(wlan_private * priv, int mode)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-
-       if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2
-           && mode != RF_ANTENNA_AUTO) {
-               return -EINVAL;
-       }
-
-       adapter->rxantennamode = mode;
-
-       lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode);
-
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-                                   cmd_act_set_rx,
-                                   cmd_option_waitforrsp, 0,
-                                   &adapter->rxantennamode);
-       return ret;
-}
-
-static int settxantenna(wlan_private * priv, int mode)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-
-       if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2)
-           && (mode != RF_ANTENNA_AUTO)) {
-               return -EINVAL;
-       }
-
-       adapter->txantennamode = mode;
-
-       lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode);
-
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-                                   cmd_act_set_tx,
-                                   cmd_option_waitforrsp, 0,
-                                   &adapter->txantennamode);
-
-       return ret;
-}
-
-static int getrxantenna(wlan_private * priv, char *buf)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-
-       // clear it, so we will know if the value
-       // returned below is correct or not.
-       adapter->rxantennamode = 0;
-
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-                                   cmd_act_get_rx,
-                                   cmd_option_waitforrsp, 0, NULL);
-
-       if (ret) {
-               LEAVE();
-               return ret;
-       }
-
-       lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode);
-
-       return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1;
-}
-
-static int gettxantenna(wlan_private * priv, char *buf)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-
-       // clear it, so we will know if the value
-       // returned below is correct or not.
-       adapter->txantennamode = 0;
-
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-                                   cmd_act_get_tx,
-                                   cmd_option_waitforrsp, 0, NULL);
-
-       if (ret) {
-               LEAVE();
-               return ret;
-       }
-
-       lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode);
-
-       return sprintf(buf, "0x%04x", adapter->txantennamode) + 1;
-}
-
-static int wlan_set_region(wlan_private * priv, u16 region_code)
-{
-       int i;
-
-       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
-               // use the region code to search for the index
-               if (region_code == libertas_region_code_to_index[i]) {
-                       priv->adapter->regiontableindex = (u16) i;
-                       priv->adapter->regioncode = region_code;
-                       break;
-               }
-       }
-
-       // if it's unidentified region code
-       if (i >= MRVDRV_MAX_REGION_CODE) {
-               lbs_pr_debug(1, "region Code not identified\n");
-               LEAVE();
-               return -1;
-       }
-
-       if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
-               LEAVE();
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/**
- *  @brief Get/Set Firmware wakeup method
- *
- *  @param priv                A pointer to wlan_private structure
- *  @param wrq         A pointer to user data
- *  @return            0--success, otherwise fail
- */
-static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int data;
-       ENTER();
-
-       if ((int)wrq->u.data.length == 0) {
-               if (copy_to_user
-                   (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) {
-                       lbs_pr_alert("copy_to_user failed!\n");
-                       return -EFAULT;
-               }
-       } else {
-               if ((int)wrq->u.data.length > 1) {
-                       lbs_pr_alert("ioctl too many args!\n");
-                       return -EFAULT;
-               }
-               if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-                       lbs_pr_alert("Copy from user failed\n");
-                       return -EFAULT;
-               }
-
-               adapter->pkttxctrl = (u32) data;
-       }
-
-       wrq->u.data.length = 1;
-
-       LEAVE();
-       return 0;
-}
-
-/**
- *  @brief Get/Set NULL Package generation interval
- *
- *  @param priv                A pointer to wlan_private structure
- *  @param wrq         A pointer to user data
- *  @return            0--success, otherwise fail
- */
-static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int data;
-       ENTER();
-
-       if ((int)wrq->u.data.length == 0) {
-               data = adapter->nullpktinterval;
-
-               if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
-                       lbs_pr_alert( "copy_to_user failed!\n");
-                       return -EFAULT;
-               }
-       } else {
-               if ((int)wrq->u.data.length > 1) {
-                       lbs_pr_alert( "ioctl too many args!\n");
-                       return -EFAULT;
-               }
-               if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-
-               adapter->nullpktinterval = data;
-       }
-
-       wrq->u.data.length = 1;
-
-       LEAVE();
-       return 0;
-}
-
-static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int data[2];
-       ENTER();
-       data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-       data[1] = adapter->rxpd_rate;
-       if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
-               lbs_pr_debug(1, "Copy to user failed\n");
-               return -EFAULT;
-       }
-       wrq->u.data.length = 2;
-       LEAVE();
-       return 0;
-}
-
-static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-       int data[4];
-
-       ENTER();
-       memset(data, 0, sizeof(data));
-       if (wrq->u.data.length) {
-               if (copy_from_user(data, wrq->u.data.pointer,
-                    min_t(size_t, wrq->u.data.length, 4) * sizeof(int)))
-                       return -EFAULT;
-       }
-       if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) {
-               if (adapter->connect_status == libertas_connected) {
-                       ret = libertas_prepare_and_send_command(priv,
-                                                   cmd_802_11_rssi,
-                                                   0,
-                                                   cmd_option_waitforrsp,
-                                                   0, NULL);
-
-                       if (ret) {
-                               LEAVE();
-                               return ret;
-                       }
-               }
-       }
-
-       if (wrq->u.data.length == 0) {
-               data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
-               data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
-               data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-               data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4))
-                       return -EFAULT;
-               wrq->u.data.length = 4;
-       } else if (data[0] == 0) {
-               data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-                       return -EFAULT;
-               wrq->u.data.length = 1;
-       } else if (data[0] == 1) {
-               data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-                       return -EFAULT;
-               wrq->u.data.length = 1;
-       } else if (data[0] == 2) {
-               data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-                       return -EFAULT;
-               wrq->u.data.length = 1;
-       } else if (data[0] == 3) {
-               data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-                       return -EFAULT;
-               wrq->u.data.length = 1;
-       } else
-               return -ENOTSUPP;
-
-       LEAVE();
-       return 0;
-}
-
-static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq)
-{
-       int data;
-       wlan_adapter *adapter = priv->adapter;
-
-       if (wrq->u.data.length > 0) {
-               if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int)))
-                       return -EFAULT;
-
-               lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data);
-               if ((data > MRVDRV_MAX_BEACON_INTERVAL)
-                   || (data < MRVDRV_MIN_BEACON_INTERVAL))
-                       return -ENOTSUPP;
-               adapter->beaconperiod = data;
-       }
-       data = adapter->beaconperiod;
-       if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int)))
-               return -EFAULT;
-
-       wrq->u.data.length = 1;
-
-       return 0;
-}
-
-static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-       int temp;
-       int data = 0;
-       int *val;
-
-       ENTER();
-       data = SUBCMD_DATA(wrq);
-       if ((data == 0) || (data == 1)) {
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_rssi,
-                                           0, cmd_option_waitforrsp,
-                                           0, NULL);
-               if (ret) {
-                       LEAVE();
-                       return ret;
-               }
-       }
-
-       switch (data) {
-       case 0:
-
-               temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
-                               adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
-               break;
-       case 1:
-               temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG],
-                               adapter->NF[TYPE_BEACON][TYPE_AVG]);
-               break;
-       case 2:
-               temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
-                               adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
-               break;
-       case 3:
-               temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
-                               adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
-               break;
-       default:
-               return -ENOTSUPP;
-       }
-       val = (int *)wrq->u.name;
-       *val = temp;
-
-       LEAVE();
-       return 0;
-}
-
-static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-       int temp;
-       int data = 0;
-       int *val;
-
-       data = SUBCMD_DATA(wrq);
-       if ((data == 0) || (data == 1)) {
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_rssi,
-                                           0, cmd_option_waitforrsp,
-                                           0, NULL);
-
-               if (ret) {
-                       LEAVE();
-                       return ret;
-               }
-       }
-
-       switch (data) {
-       case 0:
-               temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG];
-               break;
-       case 1:
-               temp = adapter->NF[TYPE_BEACON][TYPE_AVG];
-               break;
-       case 2:
-               temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG];
-               break;
-       case 3:
-               temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-               break;
-       default:
-               return -ENOTSUPP;
-       }
-
-       temp = CAL_NF(temp);
-
-       lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp);
-       val = (int *)wrq->u.name;
-       *val = temp;
-       return 0;
-}
-
-static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int *pdata;
-       struct iwreq *wrq = (struct iwreq *)req;
-       int ret = 0;
-       adapter->txrate = 0;
-       lbs_pr_debug(1, "wlan_get_txrate_ioctl\n");
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query,
-                                   cmd_act_get, cmd_option_waitforrsp,
-                                   0, NULL);
-       if (ret)
-               return ret;
-
-       pdata = (int *)wrq->u.name;
-       *pdata = (int)adapter->txrate;
-       return 0;
-}
-
-static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       char status[64];
-       wlan_adapter *adapter = priv->adapter;
-
-       memset(status, 0, sizeof(status));
-
-       switch (adapter->inframode) {
-       case wlan802_11ibss:
-               if (adapter->connect_status == libertas_connected) {
-                       if (adapter->adhoccreate)
-                               memcpy(&status, "AdhocStarted", sizeof(status));
-                       else
-                               memcpy(&status, "AdhocJoined", sizeof(status));
-               } else {
-                       memcpy(&status, "AdhocIdle", sizeof(status));
-               }
-               break;
-       case wlan802_11infrastructure:
-               memcpy(&status, "Inframode", sizeof(status));
-               break;
-       default:
-               memcpy(&status, "AutoUnknownmode", sizeof(status));
-               break;
-       }
-
-       lbs_pr_debug(1, "status = %s\n", status);
-       wrq->u.data.length = strlen(status) + 1;
-
-       if (wrq->u.data.pointer) {
-               if (copy_to_user(wrq->u.data.pointer,
-                                &status, wrq->u.data.length))
-                       return -EFAULT;
-       }
-
-       LEAVE();
-       return 0;
-}
-
-/**
- *  @brief Set/Get WPA IE
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       struct iwreq *wrq = (struct iwreq *)req;
-       wlan_adapter *adapter = priv->adapter;
-       int ret = 0;
-
-       ENTER();
-
-       if (wrq->u.data.length) {
-               if (wrq->u.data.length > sizeof(adapter->wpa_ie)) {
-                       lbs_pr_debug(1, "failed to copy WPA IE, too big \n");
-                       return -EFAULT;
-               }
-               if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer,
-                                  wrq->u.data.length)) {
-                       lbs_pr_debug(1, "failed to copy WPA IE \n");
-                       return -EFAULT;
-               }
-               adapter->wpa_ie_len = wrq->u.data.length;
-               lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len,
-                      adapter->wpa_ie[0]);
-               lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len);
-               if (adapter->wpa_ie[0] == WPA_IE)
-                       adapter->secinfo.WPAenabled = 1;
-               else if (adapter->wpa_ie[0] == WPA2_IE)
-                       adapter->secinfo.WPA2enabled = 1;
-               else {
-                       adapter->secinfo.WPAenabled = 0;
-                       adapter->secinfo.WPA2enabled = 0;
-               }
-       } else {
-               memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie));
-               adapter->wpa_ie_len = wrq->u.data.length;
-               lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n",
-                      adapter->wpa_ie_len, adapter->wpa_ie[0]);
-               adapter->secinfo.WPAenabled = 0;
-               adapter->secinfo.WPA2enabled = 0;
-       }
-
-       // enable/disable RSN in firmware if WPA is enabled/disabled
-       // depending on variable adapter->secinfo.WPAenabled is set or not
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn,
-                                   cmd_act_set, cmd_option_waitforrsp,
-                                   0, NULL);
-
-       LEAVE();
-       return ret;
-}
-
-/**
- *  @brief Set Auto prescan
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq                 A pointer to iwreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       int data;
-       wlan_adapter *adapter = priv->adapter;
-       int *val;
-
-       data = SUBCMD_DATA(wrq);
-       lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data);
-       adapter->prescan = data;
-
-       val = (int *)wrq->u.name;
-       *val = data;
-       return 0;
-}
-
-static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       struct iwreq *wrq = (struct iwreq *)req;
-       u32 mdtim;
-       int idata;
-       int ret = -EINVAL;
-
-       ENTER();
-
-       idata = SUBCMD_DATA(wrq);
-       mdtim = (u32) idata;
-       if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM)
-            && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM))
-           || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) {
-               priv->adapter->multipledtim = mdtim;
-               ret = 0;
-       }
-       if (ret)
-               lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n");
-
-       LEAVE();
-       return ret;
-}
-
-/**
- *  @brief Set authentication mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       int alg;
-       struct iwreq *wrq = (struct iwreq *)req;
-       wlan_adapter *adapter = priv->adapter;
-
-       if (wrq->u.data.flags == 0) {
-               //from iwpriv subcmd
-               alg = SUBCMD_DATA(wrq);
-       } else {
-               //from wpa_supplicant subcmd
-               if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-       }
-
-       lbs_pr_debug(1, "auth alg is %#x\n", alg);
-
-       switch (alg) {
-       case AUTH_ALG_SHARED_KEY:
-               adapter->secinfo.authmode = wlan802_11authmodeshared;
-               break;
-       case AUTH_ALG_NETWORK_EAP:
-               adapter->secinfo.authmode =
-                   wlan802_11authmodenetworkEAP;
-               break;
-       case AUTH_ALG_OPEN_SYSTEM:
-       default:
-               adapter->secinfo.authmode = wlan802_11authmodeopen;
-               break;
-       }
-       return 0;
-}
-
-/**
- *  @brief Set 802.1x authentication mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       int alg;
-       struct iwreq *wrq = (struct iwreq *)req;
-
-       if (wrq->u.data.flags == 0) {
-               //from iwpriv subcmd
-               alg = SUBCMD_DATA(wrq);
-       } else {
-               //from wpa_supplicant subcmd
-               if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-       }
-       lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg);
-       priv->adapter->secinfo.auth1xalg = alg;
-       return 0;
-}
-
-static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       int mode;
-       struct iwreq *wrq = (struct iwreq *)req;
-
-       ENTER();
-
-       if (wrq->u.data.flags == 0) {
-               //from iwpriv subcmd
-               mode = SUBCMD_DATA(wrq);
-       } else {
-               //from wpa_supplicant subcmd
-               if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-       }
-       lbs_pr_debug(1, "encryption mode is %#x\n", mode);
-       priv->adapter->secinfo.Encryptionmode = mode;
-
-       LEAVE();
-       return 0;
-}
-
-static void adjust_mtu(wlan_private * priv)
-{
-       int mtu_increment = 0;
-
-       if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
-               mtu_increment += sizeof(struct ieee80211_hdr_4addr);
-
-       if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
-               mtu_increment += max(sizeof(struct tx_radiotap_hdr),
-                                    sizeof(struct rx_radiotap_hdr));
-       priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
-           - sizeof(struct ethhdr)
-           + mtu_increment;
-}
-
-/**
- *  @brief Set Link-Layer Layer mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       int mode;
-
-       mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
-       switch (mode) {
-       case WLAN_LINKMODE_802_3:
-               priv->adapter->linkmode = mode;
-               break;
-       case WLAN_LINKMODE_802_11:
-               priv->adapter->linkmode = mode;
-               break;
-       default:
-               lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
-                      mode);
-               return -EINVAL;
-               break;
-       }
-       lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
-
-       adjust_mtu(priv);
-
-       return 0;
-}
-
-/**
- *  @brief Set Radio header mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       int mode;
-
-       mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
-       switch (mode) {
-       case WLAN_RADIOMODE_NONE:
-               priv->adapter->radiomode = mode;
-               break;
-       case WLAN_RADIOMODE_RADIOTAP:
-               priv->adapter->radiomode = mode;
-               break;
-       default:
-               lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
-                      mode);
-               return -EINVAL;
-       }
-       lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
-
-       adjust_mtu(priv);
-       return 0;
-}
-
-/**
- *  @brief Set Debug header mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req                 A pointer to ifreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-       priv->adapter->debugmode = (int)((struct ifreq *)
-                                        ((u8 *) req + 4))->ifr_data;
-       return 0;
-}
-
-static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
-                                         struct ifreq *req)
-{
-       int len;
-       char buf[8];
-       struct iwreq *wrq = (struct iwreq *)req;
-
-       lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
-       len = getrxantenna(priv, buf);
-
-       wrq->u.data.length = len;
-       if (wrq->u.data.pointer) {
-               if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
-                       lbs_pr_debug(1, "CopyToUser failed\n");
-                       return -EFAULT;
-               }
-       }
-
-       return 0;
-}
-
-static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
-                                         struct ifreq *req)
-{
-       int len;
-       char buf[8];
-       struct iwreq *wrq = (struct iwreq *)req;
-
-       lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
-       len = gettxantenna(priv, buf);
-
-       wrq->u.data.length = len;
-       if (wrq->u.data.pointer) {
-               if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
-                       lbs_pr_debug(1, "CopyToUser failed\n");
-                       return -EFAULT;
-               }
-       }
-       return 0;
-}
-
-/**
- *  @brief Get the MAC TSF value from the firmware
- *
- *  @param priv         A pointer to wlan_private structure
- *  @param wrq          A pointer to iwreq structure containing buffer
- *                      space to store a TSF value retrieved from the firmware
- *
- *  @return             0 if successful; IOCTL error code otherwise
- */
-static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       u64 tsfval;
-       int ret;
-
-       ret = libertas_prepare_and_send_command(priv,
-                                   cmd_get_tsf,
-                                   0, cmd_option_waitforrsp, 0, &tsfval);
-
-       lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
-
-       if (ret != 0) {
-               lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
-               ret = -EFAULT;
-       } else {
-               if (copy_to_user(wrq->u.data.pointer,
-                                &tsfval,
-                                min_t(size_t, wrq->u.data.length,
-                                    sizeof(tsfval))) != 0) {
-
-                       lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
-                       ret = -EFAULT;
-               } else {
-                       ret = 0;
-               }
-       }
-       return ret;
-}
-
-/**
- *  @brief Get/Set adapt rate
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq                 A pointer to iwreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret;
-       wlan_adapter *adapter = priv->adapter;
-       int data[2];
-
-       memset(data, 0, sizeof(data));
-       if (!wrq->u.data.length) {
-               lbs_pr_debug(1, "Get ADAPT RATE SET\n");
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_rate_adapt_rateset,
-                                           cmd_act_get,
-                                           cmd_option_waitforrsp, 0, NULL);
-               data[0] = adapter->enablehwauto;
-               data[1] = adapter->ratebitmap;
-               if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
-                       lbs_pr_debug(1, "Copy to user failed\n");
-                       return -EFAULT;
-               }
-#define GET_TWO_INT    2
-               wrq->u.data.length = GET_TWO_INT;
-       } else {
-               lbs_pr_debug(1, "Set ADAPT RATE SET\n");
-               if (wrq->u.data.length > 2)
-                       return -EINVAL;
-               if (copy_from_user
-                   (data, wrq->u.data.pointer,
-                    sizeof(int) * wrq->u.data.length)) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-
-               adapter->enablehwauto = data[0];
-               adapter->ratebitmap = data[1];
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_rate_adapt_rateset,
-                                           cmd_act_set,
-                                           cmd_option_waitforrsp, 0, NULL);
-       }
-       return ret;
-}
-
-/**
- *  @brief Get/Set inactivity timeout
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq                 A pointer to iwreq structure
- *  @return                    0 --success, otherwise fail
- */
-static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret;
-       int data = 0;
-       u16 timeout = 0;
-
-       ENTER();
-       if (wrq->u.data.length > 1)
-               return -ENOTSUPP;
-
-       if (wrq->u.data.length == 0) {
-               /* Get */
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_inactivity_timeout,
-                                           cmd_act_get,
-                                           cmd_option_waitforrsp, 0,
-                                           &timeout);
-               data = timeout;
-               if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
-                       lbs_pr_debug(1, "Copy to user failed\n");
-                       return -EFAULT;
-               }
-       } else {
-               /* Set */
-               if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-                       lbs_pr_debug(1, "Copy from user failed\n");
-                       return -EFAULT;
-               }
-
-               timeout = data;
-               ret = libertas_prepare_and_send_command(priv,
-                                           cmd_802_11_inactivity_timeout,
-                                           cmd_act_set,
-                                           cmd_option_waitforrsp, 0,
-                                           &timeout);
-       }
-
-       wrq->u.data.length = 1;
-
-       LEAVE();
-       return ret;
-}
-
-static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       int ret;
-       char buf[GETLOG_BUFSIZE - 1];
-       wlan_adapter *adapter = priv->adapter;
-
-       lbs_pr_debug(1, " GET STATS\n");
-
-       ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
-                                   0, cmd_option_waitforrsp, 0, NULL);
-
-       if (ret) {
-               return ret;
-       }
-
-       if (wrq->u.data.pointer) {
-               sprintf(buf, "\n  mcasttxframe %u failed %u retry %u "
-                       "multiretry %u framedup %u "
-                       "rtssuccess %u rtsfailure %u ackfailure %u\n"
-                       "rxfrag %u mcastrxframe %u fcserror %u "
-                       "txframe %u wepundecryptable %u ",
-                       adapter->logmsg.mcasttxframe,
-                       adapter->logmsg.failed,
-                       adapter->logmsg.retry,
-                       adapter->logmsg.multiretry,
-                       adapter->logmsg.framedup,
-                       adapter->logmsg.rtssuccess,
-                       adapter->logmsg.rtsfailure,
-                       adapter->logmsg.ackfailure,
-                       adapter->logmsg.rxfrag,
-                       adapter->logmsg.mcastrxframe,
-                       adapter->logmsg.fcserror,
-                       adapter->logmsg.txframe,
-                       adapter->logmsg.wepundecryptable);
-               wrq->u.data.length = strlen(buf) + 1;
-               if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
-                       lbs_pr_debug(1, "Copy to user failed\n");
-                       return -EFAULT;
-               }
-       }
-
-       return 0;
-}
-
-static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       u8 buf[12];
-       u8 *option[] = { "active", "passive", "get", };
-       int i, max_options = (sizeof(option) / sizeof(option[0]));
-       int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
-
-       if (priv->adapter->enable11d) {
-               lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
-               return -EFAULT;
-       }
-
-       memset(buf, 0, sizeof(buf));
-
-       if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
-                                                        wrq->u.data.length)))
-               return -EFAULT;
-
-       lbs_pr_debug(1, "Scan type Option = %s\n", buf);
-
-       buf[sizeof(buf) - 1] = '\0';
-
-       for (i = 0; i < max_options; i++) {
-               if (!strcmp(buf, option[i]))
-                       break;
-       }
-
-       switch (i) {
-       case 0:
-               adapter->scantype = cmd_scan_type_active;
-               break;
-       case 1:
-               adapter->scantype = cmd_scan_type_passive;
-               break;
-       case 2:
-               wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
-
-               if (copy_to_user(wrq->u.data.pointer,
-                                option[adapter->scantype],
-                                wrq->u.data.length)) {
-                       lbs_pr_debug(1, "Copy to user failed\n");
-                       ret = -EFAULT;
-               }
-
-               break;
-       default:
-               lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       wlan_adapter *adapter = priv->adapter;
-       u8 buf[12];
-       u8 *option[] = { "bss", "ibss", "any", "get" };
-       int i, max_options = (sizeof(option) / sizeof(option[0]));
-       int ret = 0;
-
-       ENTER();
-
-       memset(buf, 0, sizeof(buf));
-
-       if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
-                                                        wrq->u.data.length))) {
-               lbs_pr_debug(1, "Copy from user failed\n");
-               return -EFAULT;
-       }
-
-       lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
-
-       buf[sizeof(buf) - 1] = '\0';
+static int wlan_set_region(wlan_private * priv, u16 region_code)
+{
+       int i;
 
-       for (i = 0; i < max_options; i++) {
-               if (!strcmp(buf, option[i]))
+       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
+               // use the region code to search for the index
+               if (region_code == libertas_region_code_to_index[i]) {
+                       priv->adapter->regiontableindex = (u16) i;
+                       priv->adapter->regioncode = region_code;
                        break;
-       }
-
-       switch (i) {
-
-       case 0:
-               adapter->scanmode = cmd_bss_type_bss;
-               break;
-       case 1:
-               adapter->scanmode = cmd_bss_type_ibss;
-               break;
-       case 2:
-               adapter->scanmode = cmd_bss_type_any;
-               break;
-       case 3:
-
-               wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
-
-               lbs_pr_debug(1, "Get Scan mode Option = %s\n",
-                      option[adapter->scanmode - 1]);
-
-               lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
-
-               if (copy_to_user(wrq->u.data.pointer,
-                                option[adapter->scanmode - 1],
-                                wrq->u.data.length)) {
-                       lbs_pr_debug(1, "Copy to user failed\n");
-                       ret = -EFAULT;
                }
-               lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
-                      (char *)wrq->u.data.pointer);
-
-               break;
-
-       default:
-               lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
-               ret = -EINVAL;
-               break;
        }
 
-       LEAVE();
-       return ret;
-}
-
-/**
- *  @brief Get/Set Adhoc G Rate
- *
- *  @param priv                A pointer to wlan_private structure
- *  @param wrq         A pointer to user data
- *  @return            0--success, otherwise fail
- */
-static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int data, data1;
-       int *val;
-
-       ENTER();
+       // if it's unidentified region code
+       if (i >= MRVDRV_MAX_REGION_CODE) {
+               lbs_pr_debug(1, "region Code not identified\n");
+               LEAVE();
+               return -1;
+       }
 
-       data1 = SUBCMD_DATA(wrq);
-       switch (data1) {
-       case 0:
-               adapter->adhoc_grate_enabled = 0;
-               break;
-       case 1:
-               adapter->adhoc_grate_enabled = 1;
-               break;
-       case 2:
-               break;
-       default:
+       if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
+               LEAVE();
                return -EINVAL;
        }
-       data = adapter->adhoc_grate_enabled;
-       val = (int *)wrq->u.name;
-       *val = data;
-       LEAVE();
+
        return 0;
 }
 
@@ -1761,6 +680,7 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
 {
+       struct iwreq *wrq = (struct iwreq *)req;
        static struct cmd_ds_fwt_access fwt_access;
        int ret;
 
@@ -1776,7 +696,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
                                    (void *)&fwt_access);
 
        if (ret == 0)
-               req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+               wrq->u.param.value = le32_to_cpu(fwt_access.references);
        else
                return -EFAULT;
 
@@ -1792,6 +712,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
 {
+       struct iwreq *wrq = (struct iwreq *)req;
        static struct cmd_ds_fwt_access fwt_access;
        int ret;
 
@@ -1807,7 +728,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
                                    (void *)&fwt_access);
 
        if (ret == 0)
-               req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+               wrq->u.param.value = le32_to_cpu(fwt_access.references);
        else
                return -EFAULT;
 
@@ -1823,6 +744,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
 {
+       struct iwreq *wrq = (struct iwreq *)req;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
@@ -1835,9 +757,8 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
                                    cmd_option_waitforrsp, 0,
                                    (void *)&mesh_access);
 
-       if (ret == 0) {
-               req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
-       }
+       if (ret == 0)
+               wrq->u.param.value = le32_to_cpu(mesh_access.data[0]);
        else
                return -EFAULT;
 
@@ -1898,36 +819,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
        lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
        switch (cmd) {
-       case WLANSCAN_TYPE:
-               lbs_pr_debug(1, "Scan type Ioctl\n");
-               ret = wlan_scan_type_ioctl(priv, wrq);
-               break;
-
        case WLAN_SETNONE_GETNONE:      /* set WPA mode on/off ioctl #20 */
                switch (wrq->u.data.flags) {
-               case WLANDEAUTH:
-                       lbs_pr_debug(1, "Deauth\n");
-                       libertas_send_deauth(priv);
-                       break;
-
-               case WLANADHOCSTOP:
-                       lbs_pr_debug(1, "Adhoc stop\n");
-                       ret = libertas_do_adhocstop_ioctl(priv);
-                       break;
-
-               case WLANRADIOON:
-                       wlan_radio_ioctl(priv, 1);
-                       break;
-
-               case WLANRADIOOFF:
-                       wlan_radio_ioctl(priv, 0);
-                       break;
-               case WLANWLANIDLEON:
-                       libertas_idle_on(priv);
-                       break;
-               case WLANWLANIDLEOFF:
-                       libertas_idle_off(priv);
-                       break;
                case WLAN_SUBCMD_BT_RESET:      /* bt_reset */
                        wlan_bt_reset_ioctl(priv);
                        break;
@@ -1937,162 +830,19 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
                }               /* End of switch */
                break;
 
-       case WLANSETWPAIE:
-               ret = wlan_setwpaie_ioctl(priv, req);
-               break;
-       case WLAN_SETINT_GETINT:
-               /* The first 4 bytes of req->ifr_data is sub-ioctl number
-                * after 4 bytes sits the payload.
-                */
-               subcmd = (int)req->ifr_data;    //from iwpriv subcmd
-               switch (subcmd) {
-               case WLANNF:
-                       ret = wlan_get_nf(priv, wrq);
-                       break;
-               case WLANRSSI:
-                       ret = wlan_get_rssi(priv, wrq);
-                       break;
-               case WLANENABLE11D:
-                       ret = libertas_cmd_enable_11d(priv, wrq);
-                       break;
-               case WLANADHOCGRATE:
-                       ret = wlan_do_set_grate_ioctl(priv, wrq);
-                       break;
-               case WLAN_SUBCMD_SET_PRESCAN:
-                       ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
-                       break;
-               }
-               break;
-
-       case WLAN_SETONEINT_GETONEINT:
-               switch (wrq->u.data.flags) {
-               case WLAN_BEACON_INTERVAL:
-                       ret = wlan_beacon_interval(priv, wrq);
-                       break;
-
-               case WLAN_LISTENINTRVL:
-                       if (!wrq->u.data.length) {
-                               int data;
-                               lbs_pr_debug(1, "Get locallisteninterval value\n");
-#define GET_ONE_INT    1
-                               data = adapter->locallisteninterval;
-                               if (copy_to_user(wrq->u.data.pointer,
-                                                &data, sizeof(int))) {
-                                       lbs_pr_debug(1, "Copy to user failed\n");
-                                       return -EFAULT;
-                               }
-
-                               wrq->u.data.length = GET_ONE_INT;
-                       } else {
-                               int data;
-                               if (copy_from_user
-                                   (&data, wrq->u.data.pointer, sizeof(int))) {
-                                       lbs_pr_debug(1, "Copy from user failed\n");
-                                       return -EFAULT;
-                               }
-
-                               lbs_pr_debug(1, "Set locallisteninterval = %d\n",
-                                      data);
-#define MAX_U16_VAL    65535
-                               if (data > MAX_U16_VAL) {
-                                       lbs_pr_debug(1, "Exceeds U16 value\n");
-                                       return -EINVAL;
-                               }
-                               adapter->locallisteninterval = data;
-                       }
-                       break;
-               case WLAN_TXCONTROL:
-                       ret = wlan_txcontrol(priv, wrq);        //adds for txcontrol ioctl
-                       break;
-
-               case WLAN_NULLPKTINTERVAL:
-                       ret = wlan_null_pkt_interval(priv, wrq);
-                       break;
-
-               default:
-                       ret = -EOPNOTSUPP;
-                       break;
-               }
-               break;
-
        case WLAN_SETONEINT_GETNONE:
                /* The first 4 bytes of req->ifr_data is sub-ioctl number
                 * after 4 bytes sits the payload.
                 */
-               subcmd = wrq->u.data.flags;     //from wpa_supplicant subcmd
-
+               subcmd = wrq->u.data.flags;
                if (!subcmd)
-                       subcmd = (int)req->ifr_data;    //from iwpriv subcmd
+                       subcmd = (int)wrq->u.param.value;
 
                switch (subcmd) {
-               case WLAN_SUBCMD_SETRXANTENNA:  /* SETRXANTENNA */
-                       idata = SUBCMD_DATA(wrq);
-                       ret = setrxantenna(priv, idata);
-                       break;
-               case WLAN_SUBCMD_SETTXANTENNA:  /* SETTXANTENNA */
-                       idata = SUBCMD_DATA(wrq);
-                       ret = settxantenna(priv, idata);
-                       break;
-               case WLAN_SET_ATIM_WINDOW:
-                       adapter->atimwindow = SUBCMD_DATA(wrq);
-                       adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
-                       break;
-               case WLANSETBCNAVG:
-                       adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
-                       if (adapter->bcn_avg_factor == 0)
-                               adapter->bcn_avg_factor =
-                                   DEFAULT_BCN_AVG_FACTOR;
-                       if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
-                               adapter->bcn_avg_factor =
-                                   DEFAULT_BCN_AVG_FACTOR;
-                       break;
-               case WLANSETDATAAVG:
-                       adapter->data_avg_factor = SUBCMD_DATA(wrq);
-                       if (adapter->data_avg_factor == 0)
-                               adapter->data_avg_factor =
-                                   DEFAULT_DATA_AVG_FACTOR;
-                       if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
-                               adapter->data_avg_factor =
-                                   DEFAULT_DATA_AVG_FACTOR;
-                       break;
                case WLANSETREGION:
                        idata = SUBCMD_DATA(wrq);
                        ret = wlan_set_region(priv, (u16) idata);
                        break;
-
-               case WLAN_SET_LISTEN_INTERVAL:
-                       idata = SUBCMD_DATA(wrq);
-                       adapter->listeninterval = (u16) idata;
-                       break;
-
-               case WLAN_SET_MULTIPLE_DTIM:
-                       ret = wlan_set_multiple_dtim_ioctl(priv, req);
-                       break;
-
-               case WLANSETAUTHALG:
-                       ret = wlan_setauthalg_ioctl(priv, req);
-                       break;
-
-               case WLANSET8021XAUTHALG:
-                       ret = wlan_set8021xauthalg_ioctl(priv, req);
-                       break;
-
-               case WLANSETENCRYPTIONMODE:
-                       ret = wlan_setencryptionmode_ioctl(priv, req);
-                       break;
-
-               case WLAN_SET_LINKMODE:
-                       ret = wlan_set_linkmode_ioctl(priv, req);
-                       break;
-
-               case WLAN_SET_RADIOMODE:
-                       ret = wlan_set_radiomode_ioctl(priv, req);
-                       break;
-
-               case WLAN_SET_DEBUGMODE:
-                       ret = wlan_set_debugmode_ioctl(priv, req);
-                       break;
-
                case WLAN_SUBCMD_MESH_SET_TTL:
                        idata = SUBCMD_DATA(wrq);
                        ret = wlan_mesh_set_ttl_ioctl(priv, idata);
@@ -2105,38 +855,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
                break;
 
-       case WLAN_SETNONE_GETTWELVE_CHAR:       /* Get Antenna settings */
-               /*
-                * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
-                * in flags of iwreq structure, otherwise it will be in
-                * mode member of iwreq structure.
-                */
-               switch ((int)wrq->u.data.flags) {
-               case WLAN_SUBCMD_GETRXANTENNA:  /* Get Rx Antenna */
-                       ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
-                       break;
-
-               case WLAN_SUBCMD_GETTXANTENNA:  /* Get Tx Antenna */
-                       ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
-                       break;
-
-               case WLAN_GET_TSF:
-                       ret = wlan_get_tsf_ioctl(priv, wrq);
-                       break;
-               }
-               break;
-
        case WLAN_SET128CHAR_GET128CHAR:
                switch ((int)wrq->u.data.flags) {
-
-               case WLANSCAN_MODE:
-                       lbs_pr_debug(1, "Scan mode Ioctl\n");
-                       ret = wlan_scan_mode_ioctl(priv, wrq);
-                       break;
-
-               case WLAN_GET_ADHOC_STATUS:
-                       ret = wlan_get_adhoc_status_ioctl(priv, wrq);
-                       break;
                case WLAN_SUBCMD_BT_ADD:
                        ret = wlan_bt_add_ioctl(priv, req);
                        break;
@@ -2168,41 +888,11 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
                break;
 
        case WLAN_SETNONE_GETONEINT:
-               switch ((int)req->ifr_data) {
-               case WLANGETBCNAVG:
-                       pdata = (int *)wrq->u.name;
-                       *pdata = (int)adapter->bcn_avg_factor;
-                       break;
-
+               switch (wrq->u.param.value) {
                case WLANGETREGION:
                        pdata = (int *)wrq->u.name;
                        *pdata = (int)adapter->regioncode;
                        break;
-
-               case WLAN_GET_LISTEN_INTERVAL:
-                       pdata = (int *)wrq->u.name;
-                       *pdata = (int)adapter->listeninterval;
-                       break;
-
-               case WLAN_GET_LINKMODE:
-                       req->ifr_data = (char *)((u32) adapter->linkmode);
-                       break;
-
-               case WLAN_GET_RADIOMODE:
-                       req->ifr_data = (char *)((u32) adapter->radiomode);
-                       break;
-
-               case WLAN_GET_DEBUGMODE:
-                       req->ifr_data = (char *)((u32) adapter->debugmode);
-                       break;
-
-               case WLAN_GET_MULTIPLE_DTIM:
-                       pdata = (int *)wrq->u.name;
-                       *pdata = (int)adapter->multipledtim;
-                       break;
-               case WLAN_GET_TX_RATE:
-                       ret = wlan_get_txrate_ioctl(priv, req);
-                       break;
                case WLAN_SUBCMD_FWT_CLEANUP:   /* fwt_cleanup */
                        ret = wlan_fwt_cleanup_ioctl(priv, req);
                        break;
@@ -2222,196 +912,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
                break;
 
-       case WLANGETLOG:
-               ret = wlan_do_getlog_ioctl(priv, wrq);
-               break;
-
        case WLAN_SET_GET_SIXTEEN_INT:
                switch ((int)wrq->u.data.flags) {
-               case WLAN_TPCCFG:
-                       {
-                               int data[5];
-                               struct cmd_ds_802_11_tpc_cfg cfg;
-                               memset(&cfg, 0, sizeof(cfg));
-                               if ((wrq->u.data.length > 1)
-                                   && (wrq->u.data.length != 5))
-                                       return -1;
-
-                               if (wrq->u.data.length == 0) {
-                                       cfg.action =
-                                           cpu_to_le16
-                                           (cmd_act_get);
-                               } else {
-                                       if (copy_from_user
-                                           (data, wrq->u.data.pointer,
-                                            sizeof(int) * 5)) {
-                                               lbs_pr_debug(1,
-                                                      "Copy from user failed\n");
-                                               return -EFAULT;
-                                       }
-
-                                       cfg.action =
-                                           cpu_to_le16
-                                           (cmd_act_set);
-                                       cfg.enable = data[0];
-                                       cfg.usesnr = data[1];
-                                       cfg.P0 = data[2];
-                                       cfg.P1 = data[3];
-                                       cfg.P2 = data[4];
-                               }
-
-                               ret =
-                                   libertas_prepare_and_send_command(priv,
-                                                         cmd_802_11_tpc_cfg,
-                                                         0,
-                                                         cmd_option_waitforrsp,
-                                                         0, (void *)&cfg);
-
-                               data[0] = cfg.enable;
-                               data[1] = cfg.usesnr;
-                               data[2] = cfg.P0;
-                               data[3] = cfg.P1;
-                               data[4] = cfg.P2;
-                               if (copy_to_user
-                                   (wrq->u.data.pointer, data,
-                                    sizeof(int) * 5)) {
-                                       lbs_pr_debug(1, "Copy to user failed\n");
-                                       return -EFAULT;
-                               }
-
-                               wrq->u.data.length = 5;
-                       }
-                       break;
-
-               case WLAN_POWERCFG:
-                       {
-                               int data[4];
-                               struct cmd_ds_802_11_pwr_cfg cfg;
-                               memset(&cfg, 0, sizeof(cfg));
-                               if ((wrq->u.data.length > 1)
-                                   && (wrq->u.data.length != 4))
-                                       return -1;
-                               if (wrq->u.data.length == 0) {
-                                       cfg.action =
-                                           cpu_to_le16
-                                           (cmd_act_get);
-                               } else {
-                                       if (copy_from_user
-                                           (data, wrq->u.data.pointer,
-                                            sizeof(int) * 4)) {
-                                               lbs_pr_debug(1,
-                                                      "Copy from user failed\n");
-                                               return -EFAULT;
-                                       }
-
-                                       cfg.action =
-                                           cpu_to_le16
-                                           (cmd_act_set);
-                                       cfg.enable = data[0];
-                                       cfg.PA_P0 = data[1];
-                                       cfg.PA_P1 = data[2];
-                                       cfg.PA_P2 = data[3];
-                               }
-                               ret =
-                                   libertas_prepare_and_send_command(priv,
-                                                         cmd_802_11_pwr_cfg,
-                                                         0,
-                                                         cmd_option_waitforrsp,
-                                                         0, (void *)&cfg);
-                               data[0] = cfg.enable;
-                               data[1] = cfg.PA_P0;
-                               data[2] = cfg.PA_P1;
-                               data[3] = cfg.PA_P2;
-                               if (copy_to_user
-                                   (wrq->u.data.pointer, data,
-                                    sizeof(int) * 4)) {
-                                       lbs_pr_debug(1, "Copy to user failed\n");
-                                       return -EFAULT;
-                               }
-
-                               wrq->u.data.length = 4;
-                       }
-                       break;
-               case WLAN_AUTO_FREQ_SET:
-                       {
-                               int data[3];
-                               struct cmd_ds_802_11_afc afc;
-                               memset(&afc, 0, sizeof(afc));
-                               if (wrq->u.data.length != 3)
-                                       return -1;
-                               if (copy_from_user
-                                   (data, wrq->u.data.pointer,
-                                    sizeof(int) * 3)) {
-                                       lbs_pr_debug(1, "Copy from user failed\n");
-                                       return -EFAULT;
-                               }
-                               afc.afc_auto = data[0];
-
-                               if (afc.afc_auto != 0) {
-                                       afc.threshold = data[1];
-                                       afc.period = data[2];
-                               } else {
-                                       afc.timing_offset = data[1];
-                                       afc.carrier_offset = data[2];
-                               }
-                               ret =
-                                   libertas_prepare_and_send_command(priv,
-                                                         cmd_802_11_set_afc,
-                                                         0,
-                                                         cmd_option_waitforrsp,
-                                                         0, (void *)&afc);
-                       }
-                       break;
-               case WLAN_AUTO_FREQ_GET:
-                       {
-                               int data[3];
-                               struct cmd_ds_802_11_afc afc;
-                               memset(&afc, 0, sizeof(afc));
-                               ret =
-                                   libertas_prepare_and_send_command(priv,
-                                                         cmd_802_11_get_afc,
-                                                         0,
-                                                         cmd_option_waitforrsp,
-                                                         0, (void *)&afc);
-                               data[0] = afc.afc_auto;
-                               data[1] = afc.timing_offset;
-                               data[2] = afc.carrier_offset;
-                               if (copy_to_user
-                                   (wrq->u.data.pointer, data,
-                                    sizeof(int) * 3)) {
-                                       lbs_pr_debug(1, "Copy to user failed\n");
-                                       return -EFAULT;
-                               }
-
-                               wrq->u.data.length = 3;
-                       }
-                       break;
-               case WLAN_SCANPROBES:
-                       {
-                               int data;
-                               if (wrq->u.data.length > 0) {
-                                       if (copy_from_user
-                                           (&data, wrq->u.data.pointer,
-                                            sizeof(int))) {
-                                               lbs_pr_debug(1,
-                                                      "Copy from user failed\n");
-                                               return -EFAULT;
-                                       }
-
-                                       adapter->scanprobes = data;
-                               } else {
-                                       data = adapter->scanprobes;
-                                       if (copy_to_user
-                                           (wrq->u.data.pointer, &data,
-                                            sizeof(int))) {
-                                               lbs_pr_debug(1,
-                                                      "Copy to user failed\n");
-                                               return -EFAULT;
-                                       }
-                               }
-                               wrq->u.data.length = 1;
-                       }
-                       break;
                case WLAN_LED_GPIO_CTRL:
                        {
                                int i;
@@ -2475,17 +977,6 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
                                wrq->u.data.length = gpio->header.len;
                        }
                        break;
-               case WLAN_ADAPT_RATESET:
-                       ret = wlan_adapt_rateset(priv, wrq);
-                       break;
-               case WLAN_INACTIVITY_TIMEOUT:
-                       ret = wlan_inactivity_timeout(priv, wrq);
-                       break;
-               case WLANSNR:
-                       ret = wlan_get_snr(priv, wrq);
-                       break;
-               case WLAN_GET_RXINFO:
-                       ret = wlan_get_rxinfo(priv, wrq);
                }
                break;
 
index 11682cbe752b841ffb37e497a69a7abcf9d1b9d0..d4926b83e14549fe5d1569473721a78b119c494d 100644 (file)
@@ -15,6 +15,8 @@
 #include "join.h"
 #include "dev.h"
 
+#define AD_HOC_CAP_PRIVACY_ON 1
+
 /**
  *  @brief This function finds out the common rates between rate1 and rate2.
  *
@@ -85,7 +87,7 @@ int libertas_send_deauth(wlan_private * priv)
        wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
-       if (adapter->inframode == wlan802_11infrastructure &&
+       if (adapter->mode == IW_MODE_INFRA &&
            adapter->connect_status == libertas_connected)
                ret = libertas_send_deauthentication(priv);
        else
@@ -94,20 +96,6 @@ int libertas_send_deauth(wlan_private * priv)
        return ret;
 }
 
-int libertas_do_adhocstop_ioctl(wlan_private * priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int ret = 0;
-
-       if (adapter->inframode == wlan802_11ibss &&
-           adapter->connect_status == libertas_connected)
-               ret = libertas_stop_adhoc_network(priv);
-       else
-               ret = -ENOTSUPP;
-
-       return ret;
-}
-
 /**
  *  @brief Associate to a specific BSS discovered in a scan
  *
@@ -207,8 +195,7 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs
        /* check if the requested SSID is already joined */
        if (adapter->curbssparams.ssid.ssidlength
            && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
-           && (adapter->curbssparams.bssdescriptor.inframode ==
-               wlan802_11ibss)) {
+           && (adapter->mode == IW_MODE_ADHOC)) {
 
         lbs_pr_debug(1,
                       "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
@@ -260,130 +247,6 @@ int libertas_send_deauthentication(wlan_private * priv)
                                     0, cmd_option_waitforrsp, 0, NULL);
 }
 
-/**
- *  @brief Set Idle Off
- *
- *  @param priv         A pointer to wlan_private structure
- *  @return             0 --success, otherwise fail
- */
-int libertas_idle_off(wlan_private * priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int ret = 0;
-       const u8 zeromac[] = { 0, 0, 0, 0, 0, 0 };
-       int i;
-
-       ENTER();
-
-       if (adapter->connect_status == libertas_disconnected) {
-               if (adapter->inframode == wlan802_11infrastructure) {
-                       if (memcmp(adapter->previousbssid, zeromac,
-                                  sizeof(zeromac)) != 0) {
-
-                               lbs_pr_debug(1, "Previous SSID = %s\n",
-                                      adapter->previousssid.ssid);
-                               lbs_pr_debug(1, "Previous BSSID = "
-                                      "%02x:%02x:%02x:%02x:%02x:%02x:\n",
-                                      adapter->previousbssid[0],
-                                      adapter->previousbssid[1],
-                                      adapter->previousbssid[2],
-                                      adapter->previousbssid[3],
-                                      adapter->previousbssid[4],
-                                      adapter->previousbssid[5]);
-
-                               i = libertas_find_SSID_in_list(adapter,
-                                                  &adapter->previousssid,
-                                                  adapter->previousbssid,
-                                                  adapter->inframode);
-
-                               if (i < 0) {
-                                       libertas_send_specific_BSSID_scan(priv,
-                                                             adapter->
-                                                             previousbssid,
-                                                             1);
-                                       i = libertas_find_SSID_in_list(adapter,
-                                                          &adapter->
-                                                          previousssid,
-                                                          adapter->
-                                                          previousbssid,
-                                                          adapter->
-                                                          inframode);
-                               }
-
-                               if (i < 0) {
-                                       /* If the BSSID could not be found, try just the SSID */
-                                       i = libertas_find_SSID_in_list(adapter,
-                                                          &adapter->
-                                                          previousssid, NULL,
-                                                          adapter->
-                                                          inframode);
-                               }
-
-                               if (i < 0) {
-                                       libertas_send_specific_SSID_scan(priv,
-                                                            &adapter->
-                                                            previousssid,
-                                                            1);
-                                       i = libertas_find_SSID_in_list(adapter,
-                                                          &adapter->
-                                                          previousssid, NULL,
-                                                          adapter->
-                                                          inframode);
-                               }
-
-                               if (i >= 0) {
-                                       ret =
-                                           wlan_associate(priv,
-                                                          &adapter->
-                                                          scantable[i]);
-                               }
-                       }
-               } else if (adapter->inframode == wlan802_11ibss) {
-                       ret = libertas_prepare_and_send_command(priv,
-                                                   cmd_802_11_ad_hoc_start,
-                                                   0,
-                                                   cmd_option_waitforrsp,
-                                                   0, &adapter->previousssid);
-               }
-       }
-       /* else it is connected */
-
-       lbs_pr_debug(1, "\nwlanidle is off");
-       LEAVE();
-       return ret;
-}
-
-/**
- *  @brief Set Idle On
- *
- *  @param priv         A pointer to wlan_private structure
- *  @return             0 --success, otherwise fail
- */
-int libertas_idle_on(wlan_private * priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int ret = 0;
-
-       if (adapter->connect_status == libertas_connected) {
-               if (adapter->inframode == wlan802_11infrastructure) {
-                       lbs_pr_debug(1, "Previous SSID = %s\n",
-                              adapter->previousssid.ssid);
-                       memmove(&adapter->previousssid,
-                               &adapter->curbssparams.ssid,
-                               sizeof(struct WLAN_802_11_SSID));
-                       libertas_send_deauth(priv);
-
-               } else if (adapter->inframode == wlan802_11ibss) {
-                       ret = libertas_stop_adhoc_network(priv);
-               }
-
-       }
-
-       lbs_pr_debug(1, "\nwlanidle is on");
-
-       return ret;
-}
-
 /**
  *  @brief This function prepares command of authenticate.
  *
@@ -398,22 +261,39 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
                                 void *pdata_buf)
 {
        wlan_adapter *adapter = priv->adapter;
-       struct cmd_ds_802_11_authenticate *pauthenticate =
-           &cmd->params.auth;
+       struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
+       int ret = -1;
        u8 *bssid = pdata_buf;
 
        cmd->command = cpu_to_le16(cmd_802_11_authenticate);
-       cmd->size =
-           cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
-                            + S_DS_GEN);
+       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
+                               + S_DS_GEN);
+
+       /* translate auth mode to 802.11 defined wire value */
+       switch (adapter->secinfo.auth_mode) {
+       case IW_AUTH_ALG_OPEN_SYSTEM:
+               pauthenticate->authtype = 0x00;
+               break;
+       case IW_AUTH_ALG_SHARED_KEY:
+               pauthenticate->authtype = 0x01;
+               break;
+       case IW_AUTH_ALG_LEAP:
+               pauthenticate->authtype = 0x80;
+               break;
+       default:
+               lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n",
+                            adapter->secinfo.auth_mode);
+               goto out;
+       }
 
-       pauthenticate->authtype = adapter->secinfo.authmode;
        memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
 
        lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
               bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+       ret = 0;
 
-       return 0;
+out:
+       return ret;
 }
 
 int libertas_cmd_80211_deauthenticate(wlan_private * priv,
@@ -550,7 +430,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
        lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
 
        /* set IBSS field */
-       if (pbssdesc->inframode == wlan802_11infrastructure) {
+       if (pbssdesc->mode == IW_MODE_INFRA) {
 #define CAPINFO_ESS_MODE 1
                passo->capinfo.ess = CAPINFO_ESS_MODE;
        }
@@ -624,7 +504,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
 
        /* set the BSS type */
        adhs->bsstype = cmd_bss_type_ibss;
-       pbssdesc->inframode = wlan802_11ibss;
+       pbssdesc->mode = IW_MODE_ADHOC;
        adhs->beaconperiod = adapter->beaconperiod;
 
        /* set Physical param set */
@@ -666,15 +546,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
        adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
 
        /* set up privacy in adapter->scantable[i] */
-       if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
-
-#define AD_HOC_CAP_PRIVACY_ON 1
-               lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus set, privacy to WEP\n");
+       if (adapter->secinfo.wep_enabled) {
+               lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n");
                pbssdesc->privacy = wlan802_11privfilter8021xWEP;
                adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
        } else {
-               lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus NOT set, Setting "
-                      "privacy to ACCEPT ALL\n");
+               lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n");
                pbssdesc->privacy = wlan802_11privfilteracceptall;
        }
 
@@ -786,9 +663,6 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
               padhocjoin->bssdescriptor.BSSID[5],
               padhocjoin->bssdescriptor.SSID);
 
-       lbs_pr_debug(1, "ADHOC_J_CMD: Data Rate = %x\n",
-              (u32) padhocjoin->bssdescriptor.datarates);
-
        /* failtimeout */
        padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
 
@@ -832,7 +706,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
        padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
            cpu_to_le16(pbssdesc->atimwindow);
 
-       if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
+       if (adapter->secinfo.wep_enabled) {
                padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
        }
 
index 8efa2455af9ad3fd129d2562349359619e9782a9..115f5a8ba34603733683c329cb4171beb57c1084 100644 (file)
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Interface for the wlan infrastructure and adhoc join routines
   *
@@ -40,10 +37,6 @@ extern int libertas_ret_80211_disassociate(wlan_private * priv,
 extern int libertas_ret_80211_associate(wlan_private * priv,
                                     struct cmd_ds_command *resp);
 
-extern int libertas_idle_on(wlan_private * priv);
-extern int libertas_idle_off(wlan_private * priv);
-
-extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
 extern int libertas_reassociation_thread(void *data);
 
 struct WLAN_802_11_SSID;
index dcbf102a057e79895fdf4e662fcc5bc412ab5a92..b9b25ce6591934e1ebbb0808765dc778bf1682c9 100644 (file)
 #include "debugfs.h"
 #include "assoc.h"
 
+#define DRIVER_RELEASE_VERSION "320.p0"
+const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
+#ifdef  DEBUG
+    "-dbg"
+#endif
+    "";
+
 #ifdef ENABLE_PM
 static struct pm_dev *wlan_pm_dev = NULL;
 #endif
index 7e3f78f092dcf8613e333da99418a1086c6c6b87..d17924f764e573d5edd537aefac261c817e28f6e 100644 (file)
@@ -210,7 +210,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
                goto done;
        }
 
-       lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+       lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
               skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
        lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
@@ -364,7 +364,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
                priv->stats.rx_errors++;
        }
 
-       lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+       lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
               skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
        /* create the exported radio header */
index e18706238951df24116d6bb15c7d6e64747f7285..3c0b1a2a172748a150a9cec7c8b2f4db195f3cfd 100644 (file)
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Functions implementing wlan scan IOCTL and firmware command APIs
   *
  *
  *  @return        Index in scantable, or error code if negative
  */
-static int is_network_compatible(wlan_adapter * adapter, int index, int mode)
+static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode)
 {
        ENTER();
 
-       if (adapter->scantable[index].inframode == mode) {
-               if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+       if (adapter->scantable[index].mode == mode) {
+               if (   !adapter->secinfo.wep_enabled
                    && !adapter->secinfo.WPAenabled
                    && !adapter->secinfo.WPA2enabled
-                   && adapter->scantable[index].wpa_supplicant.wpa_ie[0] !=
-                   WPA_IE
-                   && adapter->scantable[index].wpa2_supplicant.wpa_ie[0] !=
-                   WPA2_IE && adapter->secinfo.Encryptionmode == CIPHER_NONE
+                   && adapter->scantable[index].wpa_ie[0] != WPA_IE
+                   && adapter->scantable[index].rsn_ie[0] != WPA2_IE
                    && !adapter->scantable[index].privacy) {
                        /* no security */
                        LEAVE();
                        return index;
-               } else if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled
+               } else if (   adapter->secinfo.wep_enabled
                           && !adapter->secinfo.WPAenabled
                           && !adapter->secinfo.WPA2enabled
                           && adapter->scantable[index].privacy) {
                        /* static WEP enabled */
                        LEAVE();
                        return index;
-               } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+               } else if (   !adapter->secinfo.wep_enabled
                           && adapter->secinfo.WPAenabled
                           && !adapter->secinfo.WPA2enabled
-                          && (adapter->scantable[index].wpa_supplicant.
-                              wpa_ie[0]
-                              == WPA_IE)
+                          && (adapter->scantable[index].wpa_ie[0] == WPA_IE)
                           /* privacy bit may NOT be set in some APs like LinkSys WRT54G
                              && adapter->scantable[index].privacy */
                    ) {
                        /* WPA enabled */
-            lbs_pr_debug(1,
+                       lbs_pr_debug(1,
                               "is_network_compatible() WPA: index=%d wpa_ie=%#x "
-                              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+                              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
                               "privacy=%#x\n", index,
-                              adapter->scantable[index].wpa_supplicant.
-                              wpa_ie[0],
-                              adapter->scantable[index].wpa2_supplicant.
-                              wpa_ie[0],
-                              (adapter->secinfo.WEPstatus ==
-                               wlan802_11WEPenabled) ? "e" : "d",
-                              (adapter->secinfo.WPAenabled) ? "e" : "d",
-                              (adapter->secinfo.WPA2enabled) ? "e" : "d",
-                              adapter->secinfo.Encryptionmode,
+                              adapter->scantable[index].wpa_ie[0],
+                              adapter->scantable[index].rsn_ie[0],
+                              adapter->secinfo.wep_enabled ? "e" : "d",
+                              adapter->secinfo.WPAenabled ? "e" : "d",
+                              adapter->secinfo.WPA2enabled ? "e" : "d",
                               adapter->scantable[index].privacy);
                        LEAVE();
                        return index;
-               } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+               } else if (   !adapter->secinfo.wep_enabled
                           && !adapter->secinfo.WPAenabled
                           && adapter->secinfo.WPA2enabled
-                          && (adapter->scantable[index].wpa2_supplicant.
-                              wpa_ie[0]
-                              == WPA2_IE)
+                          && (adapter->scantable[index].rsn_ie[0] == WPA2_IE)
                           /* privacy bit may NOT be set in some APs like LinkSys WRT54G
                              && adapter->scantable[index].privacy */
                    ) {
                        /* WPA2 enabled */
-            lbs_pr_debug(1,
+                       lbs_pr_debug(1,
                               "is_network_compatible() WPA2: index=%d wpa_ie=%#x "
-                              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+                              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
                               "privacy=%#x\n", index,
-                              adapter->scantable[index].wpa_supplicant.
-                              wpa_ie[0],
-                              adapter->scantable[index].wpa2_supplicant.
-                              wpa_ie[0],
-                              (adapter->secinfo.WEPstatus ==
-                               wlan802_11WEPenabled) ? "e" : "d",
-                              (adapter->secinfo.WPAenabled) ? "e" : "d",
-                              (adapter->secinfo.WPA2enabled) ? "e" : "d",
-                              adapter->secinfo.Encryptionmode,
+                              adapter->scantable[index].wpa_ie[0],
+                              adapter->scantable[index].rsn_ie[0],
+                              adapter->secinfo.wep_enabled ? "e" : "d",
+                              adapter->secinfo.WPAenabled ? "e" : "d",
+                              adapter->secinfo.WPA2enabled ? "e" : "d",
                               adapter->scantable[index].privacy);
                        LEAVE();
                        return index;
-               } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+               } else if (   !adapter->secinfo.wep_enabled
                           && !adapter->secinfo.WPAenabled
                           && !adapter->secinfo.WPA2enabled
-                          && (adapter->scantable[index].wpa_supplicant.
-                              wpa_ie[0]
-                              != WPA_IE)
-                          && (adapter->scantable[index].wpa2_supplicant.
-                              wpa_ie[0]
-                              != WPA2_IE)
-                          && adapter->secinfo.Encryptionmode != CIPHER_NONE
+                          && (adapter->scantable[index].wpa_ie[0] != WPA_IE)
+                          && (adapter->scantable[index].rsn_ie[0] != WPA2_IE)
                           && adapter->scantable[index].privacy) {
                        /* dynamic WEP enabled */
-            lbs_pr_debug(1,
+                       lbs_pr_debug(1,
                               "is_network_compatible() dynamic WEP: index=%d "
-                              "wpa_ie=%#x wpa2_ie=%#x Encmode=%#x privacy=%#x\n",
+                              "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
                               index,
-                              adapter->scantable[index].wpa_supplicant.
-                              wpa_ie[0],
-                              adapter->scantable[index].wpa2_supplicant.
-                              wpa_ie[0], adapter->secinfo.Encryptionmode,
+                              adapter->scantable[index].wpa_ie[0],
+                              adapter->scantable[index].rsn_ie[0],
                               adapter->scantable[index].privacy);
                        LEAVE();
                        return index;
                }
 
                /* security doesn't match */
-        lbs_pr_debug(1,
+               lbs_pr_debug(1,
                       "is_network_compatible() FAILED: index=%d wpa_ie=%#x "
-                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x privacy=%#x\n",
+                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
                       index,
-                      adapter->scantable[index].wpa_supplicant.wpa_ie[0],
-                      adapter->scantable[index].wpa2_supplicant.wpa_ie[0],
-                      (adapter->secinfo.WEPstatus ==
-                       wlan802_11WEPenabled) ? "e" : "d",
-                      (adapter->secinfo.WPAenabled) ? "e" : "d",
-                      (adapter->secinfo.WPA2enabled) ? "e" : "d",
-                      adapter->secinfo.Encryptionmode,
+                      adapter->scantable[index].wpa_ie[0],
+                      adapter->scantable[index].rsn_ie[0],
+                      adapter->secinfo.wep_enabled ? "e" : "d",
+                      adapter->secinfo.WPAenabled ? "e" : "d",
+                      adapter->secinfo.WPA2enabled ? "e" : "d",
                       adapter->scantable[index].privacy);
                LEAVE();
                return -ECONNREFUSED;
@@ -924,8 +898,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
        u8 founddatarateie;
        int bytesleftforcurrentbeacon;
 
-       struct WPA_SUPPLICANT *pwpa_supplicant;
-       struct WPA_SUPPLICANT *pwpa2_supplicant;
        struct IE_WPA *pIe;
        const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
 
@@ -962,9 +934,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 
        bytesleftforcurrentbeacon = beaconsize;
 
-       pwpa_supplicant = &pBSSEntry->wpa_supplicant;
-       pwpa2_supplicant = &pBSSEntry->wpa2_supplicant;
-
        memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
        lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
               pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
@@ -1027,9 +996,9 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
        }
 
        if (pcap->ibss == 1) {
-               pBSSEntry->inframode = wlan802_11ibss;
+               pBSSEntry->mode = IW_MODE_ADHOC;
        } else {
-               pBSSEntry->inframode = wlan802_11infrastructure;
+               pBSSEntry->mode = IW_MODE_INFRA;
        }
 
        /* process variable IE */
@@ -1116,7 +1085,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
                            sizeof(pcountryinfo->countrycode)
                            || pcountryinfo->len > 254) {
                                lbs_pr_debug(1, "InterpretIE: 11D- Err "
-                                      "CountryInfo len =%d min=%d max=254\n",
+                                      "CountryInfo len =%d min=%zd max=254\n",
                                       pcountryinfo->len,
                                       sizeof(pcountryinfo->countrycode));
                                LEAVE();
@@ -1160,27 +1129,27 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 #define IE_ID_LEN_FIELDS_BYTES 2
                        pIe = (struct IE_WPA *)pcurrentptr;
 
-                       if (!memcmp(pIe->oui, oui01, sizeof(oui01))) {
-                               pwpa_supplicant->wpa_ie_len
-                                   = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
-                                         sizeof(pwpa_supplicant->wpa_ie));
-                               memcpy(pwpa_supplicant->wpa_ie,
-                                      pcurrentptr,
-                                      pwpa_supplicant->wpa_ie_len);
-                               lbs_dbg_hex("InterpretIE: Resp WPA_IE",
-                                       pwpa_supplicant->wpa_ie, elemlen);
-                       }
+                       if (memcmp(pIe->oui, oui01, sizeof(oui01)))
+                               break;
+
+                       pBSSEntry->wpa_ie_len = min_t(size_t,
+                               elemlen + IE_ID_LEN_FIELDS_BYTES,
+                               sizeof(pBSSEntry->wpa_ie));
+                       memcpy(pBSSEntry->wpa_ie, pcurrentptr,
+                               pBSSEntry->wpa_ie_len);
+                       lbs_dbg_hex("InterpretIE: Resp WPA_IE",
+                               pBSSEntry->wpa_ie, elemlen);
                        break;
                case WPA2_IE:
                        pIe = (struct IE_WPA *)pcurrentptr;
-                       pwpa2_supplicant->wpa_ie_len
-                           = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
-                                 sizeof(pwpa2_supplicant->wpa_ie));
-                       memcpy(pwpa2_supplicant->wpa_ie,
-                              pcurrentptr, pwpa2_supplicant->wpa_ie_len);
 
+                       pBSSEntry->rsn_ie_len = min_t(size_t,
+                               elemlen + IE_ID_LEN_FIELDS_BYTES,
+                               sizeof(pBSSEntry->rsn_ie));
+                       memcpy(pBSSEntry->rsn_ie, pcurrentptr,
+                               pBSSEntry->rsn_ie_len);
                        lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
-                               pwpa2_supplicant->wpa_ie, elemlen);
+                               pBSSEntry->rsn_ie, elemlen);
                        break;
                case TIM:
                        break;
@@ -1227,7 +1196,7 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
  *
  *  @return         index in BSSID list, or error return code (< 0)
  */
-int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
+int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
 {
        int ret = -ENETUNREACH;
        int i;
@@ -1247,8 +1216,8 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
        for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
                if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
                        switch (mode) {
-                       case wlan802_11infrastructure:
-                       case wlan802_11ibss:
+                       case IW_MODE_INFRA:
+                       case IW_MODE_ADHOC:
                                ret = is_network_compatible(adapter, i, mode);
                                break;
                        default:
@@ -1272,7 +1241,7 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
  *  @return         index in BSSID list
  */
 int libertas_find_SSID_in_list(wlan_adapter * adapter,
-                  struct WLAN_802_11_SSID *ssid, u8 * bssid, int mode)
+                  struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
 {
        int net = -ENETUNREACH;
        u8 bestrssi = 0;
@@ -1287,8 +1256,8 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
                     !memcmp(adapter->scantable[i].
                             macaddress, bssid, ETH_ALEN))) {
                        switch (mode) {
-                       case wlan802_11infrastructure:
-                       case wlan802_11ibss:
+                       case IW_MODE_INFRA:
+                       case IW_MODE_ADHOC:
                                j = is_network_compatible(adapter, i, mode);
 
                                if (j >= 0) {
@@ -1311,7 +1280,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
                                        }
                                }
                                break;
-                       case wlan802_11autounknown:
+                       case IW_MODE_AUTO:
                        default:
                                if (SCAN_RSSI(adapter->scantable[i].rssi)
                                    > bestrssi) {
@@ -1338,8 +1307,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
  *
  *  @return         index in BSSID list
  */
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode)
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
 {
        int bestnet = -ENETUNREACH;
        u8 bestrssi = 0;
@@ -1351,8 +1319,8 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
 
        for (i = 0; i < adapter->numinscantable; i++) {
                switch (mode) {
-               case wlan802_11infrastructure:
-               case wlan802_11ibss:
+               case IW_MODE_INFRA:
+               case IW_MODE_ADHOC:
                        if (is_network_compatible(adapter, i, mode) >= 0) {
                                if (SCAN_RSSI(adapter->scantable[i].rssi) >
                                    bestrssi) {
@@ -1363,7 +1331,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
                                }
                        }
                        break;
-               case wlan802_11autounknown:
+               case IW_MODE_AUTO:
                default:
                        if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
                                bestrssi =
@@ -1388,8 +1356,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
  */
 int libertas_find_best_network_SSID(wlan_private * priv,
                                     struct WLAN_802_11_SSID *pSSID,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode)
+                                    u8 preferred_mode, u8 *out_mode)
 {
        wlan_adapter *adapter = priv->adapter;
        int ret = 0;
@@ -1414,7 +1381,7 @@ int libertas_find_best_network_SSID(wlan_private * priv,
        preqbssid = &adapter->scantable[i];
        memcpy(pSSID, &preqbssid->ssid,
               sizeof(struct WLAN_802_11_SSID));
-       *out_mode = preqbssid->inframode;
+       *out_mode = preqbssid->mode;
 
        if (!pSSID->ssidlength) {
                ret = -1;
@@ -1584,7 +1551,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
        for (i = 0; i < adapter->numinscantable; i++) {
                if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
                        lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
-                              "MAX_SCAN_CELL_SIZE=%d\n",
+                              "MAX_SCAN_CELL_SIZE=%zd\n",
                               i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
                        break;
                }
@@ -1632,7 +1599,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 
                //Add mode
                iwe.cmd = SIOCGIWMODE;
-               iwe.u.mode = adapter->scantable[i].inframode + 1;
+               iwe.u.mode = adapter->scantable[i].mode;
                iwe.len = IW_EV_UINT_LEN;
                current_ev =
                    iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
@@ -1666,7 +1633,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
                        iwe.u.qual.noise =
                            CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
                }
-               if ((adapter->inframode == wlan802_11ibss) &&
+               if ((adapter->mode == IW_MODE_ADHOC) &&
                    !libertas_SSID_cmp(&adapter->curbssparams.ssid,
                             &adapter->scantable[i].ssid)
                    && adapter->adhoccreate) {
@@ -1731,7 +1698,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
                                                 end_buf, &iwe, iwe.len);
 
                }
-               if ((adapter->scantable[i].inframode == wlan802_11ibss)
+               if ((adapter->scantable[i].mode == IW_MODE_ADHOC)
                    && !libertas_SSID_cmp(&adapter->curbssparams.ssid,
                                &adapter->scantable[i].ssid)
                    && adapter->adhoccreate) {
@@ -1745,30 +1712,24 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
                /* Add new value to event */
                current_val = current_ev + IW_EV_LCP_LEN;
 
-               if (adapter->scantable[i].wpa2_supplicant.wpa_ie[0] == WPA2_IE) {
+               if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) {
                        memset(&iwe, 0, sizeof(iwe));
                        memset(buf, 0, sizeof(buf));
-                       memcpy(buf, adapter->scantable[i].
-                                               wpa2_supplicant.wpa_ie,
-                                       adapter->scantable[i].wpa2_supplicant.
-                                               wpa_ie_len);
+                       memcpy(buf, adapter->scantable[i].rsn_ie,
+                                       adapter->scantable[i].rsn_ie_len);
                        iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = adapter->scantable[i].
-                                       wpa2_supplicant.wpa_ie_len;
+                       iwe.u.data.length = adapter->scantable[i].rsn_ie_len;
                        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
                        current_ev = iwe_stream_add_point(current_ev, end_buf,
                                        &iwe, buf);
                }
-               if (adapter->scantable[i].wpa_supplicant.wpa_ie[0] == WPA_IE) {
+               if (adapter->scantable[i].wpa_ie[0] == WPA_IE) {
                        memset(&iwe, 0, sizeof(iwe));
                        memset(buf, 0, sizeof(buf));
-                       memcpy(buf, adapter->scantable[i].
-                                               wpa_supplicant.wpa_ie,
-                                       adapter->scantable[i].wpa_supplicant.
-                                               wpa_ie_len);
+                       memcpy(buf, adapter->scantable[i].wpa_ie,
+                                       adapter->scantable[i].wpa_ie_len);
                        iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = adapter->scantable[i].
-                                       wpa_supplicant.wpa_ie_len;
+                       iwe.u.data.length = adapter->scantable[i].wpa_ie_len;
                        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
                        current_ev = iwe_stream_add_point(current_ev, end_buf,
                                        &iwe, buf);
index d93aa7fa44fd9ad3c19815d0d03fa5fec2279420..405f4f0fe575b2164295c6475cc78c1634e76558 100644 (file)
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Interface for the wlan network scan routines
   *
@@ -10,6 +7,7 @@
 #ifndef _WLAN_SCAN_H
 #define _WLAN_SCAN_H
 
+#include <net/ieee80211.h>
 #include "hostcmd.h"
 
 /**
@@ -155,7 +153,7 @@ struct bss_descriptor {
 
        u32 atimwindow;
 
-       enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+       u8 mode;
        u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
 
        int extra_ie;
@@ -170,22 +168,22 @@ struct bss_descriptor {
 
        struct ieeetypes_countryinfofullset countryinfo;
 
-       struct WPA_SUPPLICANT wpa_supplicant;
-       struct WPA_SUPPLICANT wpa2_supplicant;
-
+       u8 wpa_ie[MAX_WPA_IE_LEN];
+       size_t wpa_ie_len;
+       u8 rsn_ie[MAX_WPA_IE_LEN];
+       size_t rsn_ie_len;
 };
 
 extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
                   struct WLAN_802_11_SSID *ssid2);
 extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
-                         u8 * bssid, int mode);
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter, enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode);
-extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode);
+                         u8 * bssid, u8 mode);
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode);
+extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode);
 
 int libertas_find_best_network_SSID(wlan_private * priv,
                        struct WLAN_802_11_SSID *pSSID,
-                       enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
-                       enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode);
+                       u8 preferred_mode, u8 *out_mode);
 
 extern int libertas_send_specific_SSID_scan(wlan_private * priv,
                                struct WLAN_802_11_SSID *prequestedssid,
index 82d06223043e50c1024a7295a99b3c79bb61d85e..d4b13478c9a7efaf3c48c5fda957c2df46b73d21 100644 (file)
@@ -78,7 +78,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
                         min_t(unsigned int, skb->len, 100));
 
        if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
-               lbs_pr_debug(1, "Tx error: Bad skb length %d : %d\n",
+               lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n",
                       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
                ret = -1;
                goto done;
index e86f65ae79b8b9fc495e02881a8093a1245553a1..8b137891791fe96927ad78e64b0aad7bded08bdc 100644 (file)
@@ -1,8 +1 @@
-#define DRIVER_RELEASE_VERSION "320.p0"
-const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
-#ifdef  DEBUG
-    "-dbg"
-#endif
-    "";
-
 
index 4a52336bc0f65cf134b503544728a431fa96a438..69f52b6e59c865d58a7583d6521d00c370e56a7a 100644 (file)
@@ -17,7 +17,6 @@
 #include "defs.h"
 #include "dev.h"
 #include "join.h"
-#include "version.h"
 #include "wext.h"
 #include "assoc.h"
 
@@ -233,7 +232,7 @@ static int changeadhocchannel(wlan_private * priv, int channel)
 
                // find out the BSSID that matches the current SSID
                i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
-                                  wlan802_11ibss);
+                                  IW_MODE_ADHOC);
 
                if (i >= 0) {
                        lbs_pr_debug(1, "SSID found at %d in List,"
@@ -316,13 +315,11 @@ static int get_active_data_rates(wlan_adapter * adapter,
        ENTER();
 
        if (adapter->connect_status != libertas_connected) {
-               if (adapter->inframode == wlan802_11infrastructure) {
-                       //Infra. mode
+               if (adapter->mode == IW_MODE_INFRA) {
                        lbs_pr_debug(1, "Infra\n");
                        k = copyrates(rates, k, libertas_supported_rates,
                                      sizeof(libertas_supported_rates));
                } else {
-                       //ad-hoc mode
                        lbs_pr_debug(1, "Adhoc G\n");
                        k = copyrates(rates, k, libertas_adhoc_rates_g,
                                      sizeof(libertas_adhoc_rates_g));
@@ -586,20 +583,7 @@ static int wlan_get_mode(struct net_device *dev,
 
        ENTER();
 
-       switch (adapter->inframode) {
-       case wlan802_11ibss:
-               *uwrq = IW_MODE_ADHOC;
-               break;
-
-       case wlan802_11infrastructure:
-               *uwrq = IW_MODE_INFRA;
-               break;
-
-       default:
-       case wlan802_11autounknown:
-               *uwrq = IW_MODE_AUTO;
-               break;
-       }
+       *uwrq = adapter->mode;
 
        LEAVE();
        return 0;
@@ -1002,148 +986,17 @@ static const struct iw_priv_args wlan_private_args[] = {
        /*
         * { cmd, set_args, get_args, name }
         */
-       {
-        WLANSCAN_TYPE,
-        IW_PRIV_TYPE_CHAR | 8,
-        IW_PRIV_TYPE_CHAR | 8,
-        "scantype"},
-
-       {
-        WLAN_SETINT_GETINT,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        ""},
-       {
-        WLANNF,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "getNF"},
-       {
-        WLANRSSI,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "getRSSI"},
-       {
-        WLANENABLE11D,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "enable11d"},
-       {
-        WLANADHOCGRATE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "adhocgrate"},
-
-       {
-        WLAN_SUBCMD_SET_PRESCAN,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "prescan"},
-       {
-        WLAN_SETONEINT_GETONEINT,
-        IW_PRIV_TYPE_INT | 1,
-        IW_PRIV_TYPE_INT | 1,
-        ""},
-       {
-        WLAN_BEACON_INTERVAL,
-        IW_PRIV_TYPE_INT | 1,
-        IW_PRIV_TYPE_INT | 1,
-        "bcninterval"},
-       {
-        WLAN_LISTENINTRVL,
-        IW_PRIV_TYPE_INT | 1,
-        IW_PRIV_TYPE_INT | 1,
-        "lolisteninter"},
-       {
-        WLAN_TXCONTROL,
-        IW_PRIV_TYPE_INT | 1,
-        IW_PRIV_TYPE_INT | 1,
-        "txcontrol"},
-       {
-        WLAN_NULLPKTINTERVAL,
-        IW_PRIV_TYPE_INT | 1,
-        IW_PRIV_TYPE_INT | 1,
-        "psnullinterval"},
        /* Using iwpriv sub-command feature */
        {
         WLAN_SETONEINT_GETNONE,        /* IOCTL: 24 */
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
         IW_PRIV_TYPE_NONE,
         ""},
-
-       {
-        WLAN_SUBCMD_SETRXANTENNA,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "setrxant"},
-       {
-        WLAN_SUBCMD_SETTXANTENNA,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "settxant"},
-       {
-        WLANSETAUTHALG,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "authalgs",
-        },
-       {
-        WLANSET8021XAUTHALG,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "8021xauthalgs",
-        },
-       {
-        WLANSETENCRYPTIONMODE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "encryptionmode",
-        },
        {
         WLANSETREGION,
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
         IW_PRIV_TYPE_NONE,
         "setregioncode"},
-       {
-        WLAN_SET_LISTEN_INTERVAL,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "setlisteninter"},
-       {
-        WLAN_SET_MULTIPLE_DTIM,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "setmultipledtim"},
-       {
-        WLAN_SET_ATIM_WINDOW,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "atimwindow"},
-       {
-        WLANSETBCNAVG,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "setbcnavg"},
-       {
-        WLANSETDATAAVG,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "setdataavg"},
-       {
-        WLAN_SET_LINKMODE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "linkmode"},
-       {
-        WLAN_SET_RADIOMODE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "radiomode"},
-       {
-        WLAN_SET_DEBUGMODE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE,
-        "debugmode"},
        {
         WLAN_SUBCMD_MESH_SET_TTL,
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -1159,41 +1012,6 @@ static const struct iw_priv_args wlan_private_args[] = {
         IW_PRIV_TYPE_NONE,
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
         "getregioncode"},
-       {
-        WLAN_GET_LISTEN_INTERVAL,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "getlisteninter"},
-       {
-        WLAN_GET_MULTIPLE_DTIM,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "getmultipledtim"},
-       {
-        WLAN_GET_TX_RATE,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "gettxrate"},
-       {
-        WLANGETBCNAVG,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "getbcnavg"},
-       {
-        WLAN_GET_LINKMODE,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "get_linkmode"},
-       {
-        WLAN_GET_RADIOMODE,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "get_radiomode"},
-       {
-        WLAN_GET_DEBUGMODE,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-        "get_debugmode"},
        {
         WLAN_SUBCMD_FWT_CLEANUP,
         IW_PRIV_TYPE_NONE,
@@ -1209,61 +1027,11 @@ static const struct iw_priv_args wlan_private_args[] = {
         IW_PRIV_TYPE_NONE,
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
         "mesh_get_ttl"},
-       {
-        WLAN_SETNONE_GETTWELVE_CHAR,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | 12,
-        ""},
-       {
-        WLAN_SUBCMD_GETRXANTENNA,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | 12,
-        "getrxant"},
-       {
-        WLAN_SUBCMD_GETTXANTENNA,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | 12,
-        "gettxant"},
-       {
-        WLAN_GET_TSF,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | 12,
-        "gettsf"},
        {
         WLAN_SETNONE_GETNONE,
         IW_PRIV_TYPE_NONE,
         IW_PRIV_TYPE_NONE,
         ""},
-       {
-        WLANDEAUTH,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "deauth"},
-       {
-        WLANADHOCSTOP,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "adhocstop"},
-       {
-        WLANRADIOON,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "radioon"},
-       {
-        WLANRADIOOFF,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "radiooff"},
-       {
-        WLANWLANIDLEON,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "wlanidle-on"},
-       {
-        WLANWLANIDLEOFF,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE,
-        "wlanidle-off"},
        {
         WLAN_SUBCMD_FWT_RESET,
         IW_PRIV_TYPE_NONE,
@@ -1326,91 +1094,16 @@ static const struct iw_priv_args wlan_private_args[] = {
         IW_PRIV_TYPE_CHAR | 128,
         IW_PRIV_TYPE_CHAR | 128,
         "fwt_list_route"},
-       {
-        WLANSCAN_MODE,
-        IW_PRIV_TYPE_CHAR | 128,
-        IW_PRIV_TYPE_CHAR | 128,
-        "scanmode"},
-       {
-        WLAN_GET_ADHOC_STATUS,
-        IW_PRIV_TYPE_CHAR | 128,
-        IW_PRIV_TYPE_CHAR | 128,
-        "getadhocstatus"},
-       {
-        WLAN_SETNONE_GETWORDCHAR,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | 128,
-        ""},
-       {
-        WLANSETWPAIE,
-        IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 24,
-        IW_PRIV_TYPE_NONE,
-        "setwpaie"},
-       {
-        WLANGETLOG,
-        IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE,
-        "getlog"},
        {
         WLAN_SET_GET_SIXTEEN_INT,
         IW_PRIV_TYPE_INT | 16,
         IW_PRIV_TYPE_INT | 16,
         ""},
-       {
-        WLAN_TPCCFG,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "tpccfg"},
-       {
-        WLAN_POWERCFG,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "powercfg"},
-       {
-        WLAN_AUTO_FREQ_SET,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "setafc"},
-       {
-        WLAN_AUTO_FREQ_GET,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "getafc"},
-       {
-        WLAN_SCANPROBES,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "scanprobes"},
        {
         WLAN_LED_GPIO_CTRL,
         IW_PRIV_TYPE_INT | 16,
         IW_PRIV_TYPE_INT | 16,
         "ledgpio"},
-       {
-        WLAN_ADAPT_RATESET,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "rateadapt"},
-       {
-        WLAN_INACTIVITY_TIMEOUT,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "inactivityto"},
-       {
-        WLANSNR,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "getSNR"},
-       {
-        WLAN_GET_RATE,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "getrate"},
-       {
-        WLAN_GET_RXINFO,
-        IW_PRIV_TYPE_INT | 16,
-        IW_PRIV_TYPE_INT | 16,
-        "getrxinfo"},
 };
 
 static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
@@ -1434,7 +1127,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
 
        ENTER();
 
-       priv->wstats.status = adapter->inframode;
+       priv->wstats.status = adapter->mode;
 
        /* If we're not associated, all quality values are meaningless */
        if (adapter->connect_status != libertas_connected)
@@ -1568,13 +1261,12 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
                if (!cfp) {
                        rc = -EINVAL;
                } else {
-                       if (adapter->inframode == wlan802_11ibss) {
+                       if (adapter->mode == IW_MODE_ADHOC) {
                                rc = changeadhocchannel(priv, channel);
                                /*  If station is WEP enabled, send the
                                 *  command to set WEP in firmware
                                 */
-                               if (adapter->secinfo.WEPstatus ==
-                                   wlan802_11WEPenabled) {
+                               if (adapter->secinfo.wep_enabled) {
                                        lbs_pr_debug(1, "set_freq: WEP enabled\n");
                                        ret = libertas_prepare_and_send_command(priv,
                                                                    cmd_802_11_set_wep,
@@ -1716,49 +1408,31 @@ static int wlan_set_mode(struct net_device *dev,
        wlan_private *priv = dev->priv;
        wlan_adapter *adapter = priv->adapter;
        struct assoc_request * assoc_req;
-       enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
 
        ENTER();
 
-       switch (*uwrq) {
-       case IW_MODE_ADHOC:
-               lbs_pr_debug(1, "Wanted mode is ad-hoc: current datarate=%#x\n",
-                      adapter->datarate);
-               new_mode = wlan802_11ibss;
-               adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
-               break;
-
-       case IW_MODE_INFRA:
-               lbs_pr_debug(1, "Wanted mode is Infrastructure\n");
-               new_mode = wlan802_11infrastructure;
-               break;
-
-       case IW_MODE_AUTO:
-               lbs_pr_debug(1, "Wanted mode is Auto\n");
-               new_mode = wlan802_11autounknown;
-               break;
-
-       default:
-               lbs_pr_debug(1, "Wanted mode is Unknown: 0x%x\n", *uwrq);
-               return -EINVAL;
+       if (   (*uwrq != IW_MODE_ADHOC)
+           && (*uwrq != IW_MODE_INFRA)
+           && (*uwrq != IW_MODE_AUTO)) {
+               lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq);
+               ret = -EINVAL;
+               goto out;
        }
 
        mutex_lock(&adapter->lock);
        assoc_req = wlan_get_association_request(adapter);
        if (!assoc_req) {
                ret = -ENOMEM;
+               wlan_cancel_association_work(priv);
        } else {
-               assoc_req->mode = new_mode;
-       }
-
-       if (ret == 0) {
+               assoc_req->mode = *uwrq;
                set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
                wlan_postpone_association_work(priv);
-       } else {
-               wlan_cancel_association_work(priv);
+               lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq);
        }
        mutex_unlock(&adapter->lock);
 
+out:
        LEAVE();
        return ret;
 }
@@ -1789,13 +1463,13 @@ static int wlan_get_encode(struct net_device *dev,
        dwrq->flags = 0;
 
        /* Authentication method */
-       switch (adapter->secinfo.authmode) {
-       case wlan802_11authmodeopen:
+       switch (adapter->secinfo.auth_mode) {
+       case IW_AUTH_ALG_OPEN_SYSTEM:
                dwrq->flags = IW_ENCODE_OPEN;
                break;
 
-       case wlan802_11authmodeshared:
-       case wlan802_11authmodenetworkEAP:
+       case IW_AUTH_ALG_SHARED_KEY:
+       case IW_AUTH_ALG_LEAP:
                dwrq->flags = IW_ENCODE_RESTRICTED;
                break;
        default:
@@ -1803,8 +1477,9 @@ static int wlan_get_encode(struct net_device *dev,
                break;
        }
 
-       if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
-           || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
+       if (   adapter->secinfo.wep_enabled
+           || adapter->secinfo.WPAenabled
+           || adapter->secinfo.WPA2enabled) {
                dwrq->flags &= ~IW_ENCODE_DISABLED;
        } else {
                dwrq->flags |= IW_ENCODE_DISABLED;
@@ -1818,8 +1493,7 @@ static int wlan_get_encode(struct net_device *dev,
        if (index < 0)
                index = adapter->wep_tx_keyidx;
 
-       if ((adapter->wep_keys[index].len) &&
-           (adapter->secinfo.WEPstatus == wlan802_11WEPenabled)) {
+       if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) {
                memcpy(extra, adapter->wep_keys[index].key,
                       adapter->wep_keys[index].len);
                dwrq->length = adapter->wep_keys[index].len;
@@ -1903,7 +1577,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
                assoc_req->wep_tx_keyidx = index;
        }
 
-       assoc_req->secinfo.WEPstatus = wlan802_11WEPenabled;
+       assoc_req->secinfo.wep_enabled = 1;
 
        LEAVE();
        return 0;
@@ -1932,10 +1606,10 @@ static void disable_wep(struct assoc_request *assoc_req)
        int i;
 
        /* Set Open System auth mode */
-       assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 
        /* Clear WEP keys and mark WEP as disabled */
-       assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
+       assoc_req->secinfo.wep_enabled = 0;
        for (i = 0; i < 4; i++)
                assoc_req->wep_keys[i].len = 0;
 
@@ -1987,8 +1661,7 @@ static int wlan_set_encode(struct net_device *dev,
        /* If WEP isn't enabled, or if there is no key data but a valid
         * index, set the TX key.
         */
-       if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
-           || (dwrq->length == 0 && !is_default))
+       if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
                set_tx_key = 1;
 
        ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
@@ -2001,9 +1674,9 @@ static int wlan_set_encode(struct net_device *dev,
                set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
 
        if (dwrq->flags & IW_ENCODE_RESTRICTED) {
-               assoc_req->secinfo.authmode = wlan802_11authmodeshared;
+               assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
        } else if (dwrq->flags & IW_ENCODE_OPEN) {
-               assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+               assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
        }
 
 out:
@@ -2056,30 +1729,31 @@ static int wlan_get_encodeext(struct net_device *dev,
 
        if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
            ext->alg != IW_ENCODE_ALG_WEP) {
-               if (index != 0 || adapter->inframode != wlan802_11infrastructure)
+               if (index != 0 || adapter->mode != IW_MODE_INFRA)
                        goto out;
        }
 
        dwrq->flags = index + 1;
        memset(ext, 0, sizeof(*ext));
 
-       if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled)
-           && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) {
+       if (   !adapter->secinfo.wep_enabled
+           && !adapter->secinfo.WPAenabled
+           && !adapter->secinfo.WPA2enabled) {
                ext->alg = IW_ENCODE_ALG_NONE;
                ext->key_len = 0;
                dwrq->flags |= IW_ENCODE_DISABLED;
        } else {
                u8 *key = NULL;
 
-               if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
+               if (   adapter->secinfo.wep_enabled
                    && !adapter->secinfo.WPAenabled
                    && !adapter->secinfo.WPA2enabled) {
                        ext->alg = IW_ENCODE_ALG_WEP;
                        ext->key_len = adapter->wep_keys[index].len;
                        key = &adapter->wep_keys[index].key[0];
-               } else if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) &&
-                          (adapter->secinfo.WPAenabled ||
-                           adapter->secinfo.WPA2enabled)) {
+               } else if (   !adapter->secinfo.wep_enabled
+                          && (adapter->secinfo.WPAenabled ||
+                              adapter->secinfo.WPA2enabled)) {
                        /* WPA */
                        ext->alg = IW_ENCODE_ALG_TKIP;
                        ext->key_len = 0;
@@ -2149,7 +1823,7 @@ static int wlan_set_encodeext(struct net_device *dev,
                /* If WEP isn't enabled, or if there is no key data but a valid
                 * index, or if the set-TX-key flag was passed, set the TX key.
                 */
-               if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
+               if (   !assoc_req->secinfo.wep_enabled
                    || (dwrq->length == 0 && !is_default)
                    || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY))
                        set_tx_key = 1;
@@ -2161,11 +1835,9 @@ static int wlan_set_encodeext(struct net_device *dev,
                        goto out;
 
                if (dwrq->flags & IW_ENCODE_RESTRICTED) {
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeshared;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
                } else if (dwrq->flags & IW_ENCODE_OPEN) {
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeopen;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                }
 
                /* Mark the various WEP bits as modified */
@@ -2350,15 +2022,13 @@ static int wlan_set_auth(struct net_device *dev,
                }
                if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
                        assoc_req->secinfo.WPAenabled = 1;
-                       assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeopen;
+                       assoc_req->secinfo.wep_enabled = 0;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                }
                if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) {
                        assoc_req->secinfo.WPA2enabled = 1;
-                       assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeopen;
+                       assoc_req->secinfo.wep_enabled = 0;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                }
                updated = 1;
                break;
@@ -2376,14 +2046,11 @@ static int wlan_set_auth(struct net_device *dev,
 
        case IW_AUTH_80211_AUTH_ALG:
                if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeshared;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
                } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) {
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodeopen;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                } else if (dwrq->value & IW_AUTH_ALG_LEAP) {
-                       assoc_req->secinfo.authmode =
-                           wlan802_11authmodenetworkEAP;
+                       assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP;
                } else {
                        ret = -EINVAL;
                }
@@ -2396,9 +2063,8 @@ static int wlan_set_auth(struct net_device *dev,
                            !assoc_req->secinfo.WPA2enabled) {
                                assoc_req->secinfo.WPAenabled = 1;
                                assoc_req->secinfo.WPA2enabled = 1;
-                               assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-                               assoc_req->secinfo.authmode =
-                                   wlan802_11authmodeopen;
+                               assoc_req->secinfo.wep_enabled = 0;
+                               assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                        }
                } else {
                        assoc_req->secinfo.WPAenabled = 0;
@@ -2455,19 +2121,7 @@ static int wlan_get_auth(struct net_device *dev,
                break;
 
        case IW_AUTH_80211_AUTH_ALG:
-               switch (adapter->secinfo.authmode) {
-               case wlan802_11authmodeshared:
-                       dwrq->value = IW_AUTH_ALG_SHARED_KEY;
-                       break;
-               case wlan802_11authmodeopen:
-                       dwrq->value = IW_AUTH_ALG_OPEN_SYSTEM;
-                       break;
-               case wlan802_11authmodenetworkEAP:
-                       dwrq->value = IW_AUTH_ALG_LEAP;
-                       break;
-               default:
-                       break;
-               }
+               dwrq->value = adapter->secinfo.auth_mode;
                break;
 
        case IW_AUTH_WPA_ENABLED:
index 39f367c38d901fe38ba5ec3bb965aa5d7a07a7a2..15cfaaf0797ff7b43faee11f376fe45c9e79657d 100644 (file)
 /** PRIVATE CMD ID */
 #define        WLANIOCTL                       SIOCIWFIRSTPRIV
 
-#define WLANSETWPAIE                   (WLANIOCTL + 0)
-
-#define WLAN_SETINT_GETINT             (WLANIOCTL + 7)
-#define WLANNF                                 1
-#define WLANRSSI                               2
-#define WLANENABLE11D                          5
-#define WLANADHOCGRATE                         6
-#define WLAN_SUBCMD_SET_PRESCAN                        11
-
 #define WLAN_SETNONE_GETNONE           (WLANIOCTL + 8)
-#define WLANDEAUTH                             1
-#define WLANRADIOON                            2
-#define WLANRADIOOFF                           3
-#define WLANREMOVEADHOCAES                     4
-#define WLANADHOCSTOP                          5
-#define WLANCIPHERTEST                         6
-#define WLANCRYPTOTEST                         7
-
-#define WLANWLANIDLEON                         10
-#define WLANWLANIDLEOFF                                11
 #define WLAN_SUBCMD_BT_RESET                   13
 #define WLAN_SUBCMD_FWT_RESET                  14
 
-#define WLANGETLOG                     (WLANIOCTL + 9)
-#define GETLOG_BUFSIZE  300
-
-#define WLANSCAN_TYPE                  (WLANIOCTL + 11)
-
 #define WLAN_SETNONE_GETONEINT         (WLANIOCTL + 15)
 #define WLANGETREGION                          1
-#define WLAN_GET_LISTEN_INTERVAL               2
-#define WLAN_GET_MULTIPLE_DTIM                 3
-#define WLAN_GET_TX_RATE                       4
-#define        WLANGETBCNAVG                           5
 
-#define WLAN_GET_LINKMODE                      6
-#define WLAN_GET_RADIOMODE                     7
-#define WLAN_GET_DEBUGMODE                     8
 #define WLAN_SUBCMD_FWT_CLEANUP                        15
 #define WLAN_SUBCMD_FWT_TIME                   16
 #define WLAN_SUBCMD_MESH_GET_TTL               17
 
-#define WLANREGCFRDWR                  (WLANIOCTL + 18)
-
-#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19)
-#define WLAN_SUBCMD_GETRXANTENNA    1
-#define WLAN_SUBCMD_GETTXANTENNA    2
-#define WLAN_GET_TSF                3
-
-#define WLAN_SETNONE_GETWORDCHAR       (WLANIOCTL + 21)
-#define WLANGETADHOCAES                                1
-
-#define WLAN_SETONEINT_GETONEINT       (WLANIOCTL + 23)
-#define WLAN_BEACON_INTERVAL                   1
-#define        WLAN_LISTENINTRVL                       4
-
-#define WLAN_TXCONTROL                         6
-#define WLAN_NULLPKTINTERVAL                   7
-
 #define WLAN_SETONEINT_GETNONE         (WLANIOCTL + 24)
-#define WLAN_SUBCMD_SETRXANTENNA               1
-#define WLAN_SUBCMD_SETTXANTENNA               2
-#define WLANSETAUTHALG                         5
-#define WLANSET8021XAUTHALG                    6
-#define WLANSETENCRYPTIONMODE                  7
 #define WLANSETREGION                          8
-#define WLAN_SET_LISTEN_INTERVAL               9
-
-#define WLAN_SET_MULTIPLE_DTIM                 10
-#define WLAN_SET_ATIM_WINDOW                   11
-#define WLANSETBCNAVG                          13
-#define WLANSETDATAAVG                         14
-#define WLAN_SET_LINKMODE                      15
-#define WLAN_SET_RADIOMODE                     16
-#define WLAN_SET_DEBUGMODE                     17
 #define WLAN_SUBCMD_MESH_SET_TTL               18
 
 #define WLAN_SET128CHAR_GET128CHAR     (WLANIOCTL + 25)
-#define WLANSCAN_MODE                          6
-
-#define WLAN_GET_ADHOC_STATUS                  9
-
 #define WLAN_SUBCMD_BT_ADD                     18
 #define WLAN_SUBCMD_BT_DEL                     19
 #define WLAN_SUBCMD_BT_LIST                    20
 #define WLAN_SUBCMD_FWT_LIST_ROUTE                     26
 
 #define WLAN_SET_GET_SIXTEEN_INT       (WLANIOCTL + 29)
-#define WLAN_TPCCFG                             1
-#define WLAN_POWERCFG                           2
-
-#define WLAN_AUTO_FREQ_SET                     3
-#define WLAN_AUTO_FREQ_GET                     4
 #define WLAN_LED_GPIO_CTRL                     5
-#define WLAN_SCANPROBES                        6
-#define        WLAN_ADAPT_RATESET                      8
-#define        WLAN_INACTIVITY_TIMEOUT                 9
-#define WLANSNR                                        10
-#define WLAN_GET_RATE                          11
-#define        WLAN_GET_RXINFO                         12
-
-#define WLANCMD52RDWR                  (WLANIOCTL + 30)
-#define WLANCMD53RDWR                  (WLANIOCTL + 31)
-#define CMD53BUFLEN                            32
 
-#define        REG_MAC                                 0x19
-#define        REG_BBP                                 0x1a
-#define        REG_RF                                  0x1b
-#define        REG_EEPROM                              0x59
 #define WLAN_LINKMODE_802_3                    0
 #define WLAN_LINKMODE_802_11                   2
 #define WLAN_RADIOMODE_NONE                            0
index 78cf0711d1fadd5bd670425a4e7ce732748795c2..ef07c36bccf7ea1b4868853080ce6717e7818233 100644 (file)
@@ -249,19 +249,19 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
 
 
        if (rc == PCI_SLOT_ALREADY_UP) {
-               dev_dbg(slot->pci_bus->self, "is already active\n");
+               dev_dbg(&slot->pci_bus->self->dev, "is already active\n");
                return 1; /* return 1 to user */
        }
 
        if (rc == PCI_L1_ERR) {
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "L1 failure %d with message: %s",
                        resp.resp_sub_errno, resp.resp_l1_msg);
                return -EPERM;
        }
 
        if (rc) {
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "insert failed with error %d sub-error %d\n",
                        rc, resp.resp_sub_errno);
                return -EIO;
@@ -287,25 +287,25 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
 
        if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
            (rc == PCI_SLOT_ALREADY_DOWN)) {
-               dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
+               dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path);
                return 1; /* return 1 to user */
        }
 
        if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "Cannot remove last 33MHz card\n");
                return -EPERM;
        }
 
        if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "L1 failure %d with message \n%s\n",
                        resp.resp_sub_errno, resp.resp_l1_msg);
                return -EPERM;
        }
 
        if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "remove failed with error %d sub-error %d\n",
                        rc, resp.resp_sub_errno);
                return -EIO;
@@ -317,12 +317,12 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
        if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
                pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
                pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
-               dev_dbg(slot->pci_bus->self, "remove successful\n");
+               dev_dbg(&slot->pci_bus->self->dev, "remove successful\n");
                return 0;
        }
 
        if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
-               dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
+               dev_dbg(&slot->pci_bus->self->dev,"remove failed rc = %d\n", rc);
        }
 
        return rc;
@@ -375,7 +375,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
        num_funcs = pci_scan_slot(slot->pci_bus,
                                  PCI_DEVFN(slot->device_num + 1, 0));
        if (!num_funcs) {
-               dev_dbg(slot->pci_bus->self, "no device in slot\n");
+               dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n");
                mutex_unlock(&sn_hotplug_mutex);
                return -ENODEV;
        }
@@ -427,7 +427,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
                phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
 
                if (acpi_bus_get_device(phandle, &pdevice)) {
-                       dev_dbg(slot->pci_bus->self,
+                       dev_dbg(&slot->pci_bus->self->dev,
                                "no parent device, assuming NULL\n");
                        pdevice = NULL;
                }
@@ -479,10 +479,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
        mutex_unlock(&sn_hotplug_mutex);
 
        if (rc == 0)
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "insert operation successful\n");
        else
-               dev_dbg(slot->pci_bus->self,
+               dev_dbg(&slot->pci_bus->self->dev,
                        "insert operation failed rc = %d\n", rc);
 
        return rc;
@@ -659,16 +659,16 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
                if (rc)
                        goto register_err;
        }
-       dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
+       dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n");
        return rc;
 
 register_err:
-       dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
+       dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n",
                rc);
 
 alloc_err:
        if (rc == -ENOMEM)
-               dev_dbg(pci_bus->self, "Memory allocation error\n");
+               dev_dbg(&pci_bus->self->dev, "Memory allocation error\n");
 
        /* destroy THIS element */
        if (bss_hotplug_slot)
@@ -701,10 +701,10 @@ static int sn_pci_hotplug_init(void)
 
                rc = sn_pci_bus_valid(pci_bus);
                if (rc != 1) {
-                       dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
+                       dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n");
                        continue;
                }
-               dev_dbg(pci_bus->self, "valid hotplug bus\n");
+               dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n");
 
                rc = sn_hotplug_slot_register(pci_bus);
                if (!rc) {
index e6740d1a0824d36540b415018814ab6dc3b82344..d9cbd586ae4bc282815a6b7aad16ddb3ecb523df 100644 (file)
@@ -549,8 +549,10 @@ static int msi_free_irqs(struct pci_dev* dev)
 {
        struct msi_desc *entry, *tmp;
 
-       list_for_each_entry(entry, &dev->msi_list, list)
-               BUG_ON(irq_has_action(entry->irq));
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               if (entry->irq)
+                       BUG_ON(irq_has_action(entry->irq));
+       }
 
        arch_teardown_msi_irqs(dev);
 
index 147d86f8edbf6d1c6d7186f7ee9e87242a9ac0ab..6ccc2e95930a299074550ef9c050a42011c80c98 100644 (file)
@@ -875,6 +875,7 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
index 79479e2c6966b0cb468db6f348538e8b0e19d32f..67221615e3173537ac8df7b4ba6de436dd97db3c 100644 (file)
@@ -11,6 +11,9 @@
  * 02/29/00     D.Mosberger    moved most things into hw_irq.h
  */
 
+#include <linux/types.h>
+#include <linux/cpumask.h>
+
 #define NR_IRQS                256
 #define NR_IRQ_VECTORS NR_IRQS
 
@@ -29,5 +32,8 @@ extern void disable_irq (unsigned int);
 extern void disable_irq_nosync (unsigned int);
 extern void enable_irq (unsigned int);
 extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
+bool is_affinity_mask_valid(cpumask_t cpumask);
+
+#define is_affinity_mask_valid is_affinity_mask_valid
 
 #endif /* _ASM_IA64_IRQ_H */
index 828ae00e47c1328e172cae15788dd73953f96de3..2abc98b336f3f605ac4b18213b56d7a2f13d88f4 100644 (file)
@@ -71,13 +71,15 @@ struct prev_kprobe {
 
 #define        MAX_PARAM_RSE_SIZE      (0x60+0x60/0x3f)
 /* per-cpu kprobe control block */
+#define ARCH_PREV_KPROBE_SZ 2
 struct kprobe_ctlblk {
        unsigned long kprobe_status;
        struct pt_regs jprobe_saved_regs;
        unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE];
        unsigned long *bsp;
        unsigned long cfm;
-       struct prev_kprobe prev_kprobe;
+       atomic_t prev_kprobe_index;
+       struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ];
 };
 
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)pentry
index 560c287b12330c4e4f35860297a13f28c874a52b..67552cad517339dea7791ce825ca00109d6602f3 100644 (file)
 #include <linux/mm.h>
 #include <linux/page-flags.h>
 #include <linux/threads.h>
+#include <linux/quicklist.h>
 
 #include <asm/mmu_context.h>
 
-DECLARE_PER_CPU(unsigned long *, __pgtable_quicklist);
-#define pgtable_quicklist __ia64_per_cpu_var(__pgtable_quicklist)
-DECLARE_PER_CPU(long, __pgtable_quicklist_size);
-#define pgtable_quicklist_size __ia64_per_cpu_var(__pgtable_quicklist_size)
-
-static inline long pgtable_quicklist_total_size(void)
-{
-       long ql_size = 0;
-       int cpuid;
-
-       for_each_online_cpu(cpuid) {
-               ql_size += per_cpu(__pgtable_quicklist_size, cpuid);
-       }
-       return ql_size;
-}
-
-static inline void *pgtable_quicklist_alloc(void)
-{
-       unsigned long *ret = NULL;
-
-       preempt_disable();
-
-       ret = pgtable_quicklist;
-       if (likely(ret != NULL)) {
-               pgtable_quicklist = (unsigned long *)(*ret);
-               ret[0] = 0;
-               --pgtable_quicklist_size;
-               preempt_enable();
-       } else {
-               preempt_enable();
-               ret = (unsigned long *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-       }
-
-       return ret;
-}
-
-static inline void pgtable_quicklist_free(void *pgtable_entry)
-{
-#ifdef CONFIG_NUMA
-       int nid = page_to_nid(virt_to_page(pgtable_entry));
-
-       if (unlikely(nid != numa_node_id())) {
-               free_page((unsigned long)pgtable_entry);
-               return;
-       }
-#endif
-
-       preempt_disable();
-       *(unsigned long *)pgtable_entry = (unsigned long)pgtable_quicklist;
-       pgtable_quicklist = (unsigned long *)pgtable_entry;
-       ++pgtable_quicklist_size;
-       preempt_enable();
-}
-
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-       return pgtable_quicklist_alloc();
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
 }
 
 static inline void pgd_free(pgd_t * pgd)
 {
-       pgtable_quicklist_free(pgd);
+       quicklist_free(0, NULL, pgd);
 }
 
 #ifdef CONFIG_PGTABLE_4
@@ -94,12 +41,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       return pgtable_quicklist_alloc();
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
 }
 
 static inline void pud_free(pud_t * pud)
 {
-       pgtable_quicklist_free(pud);
+       quicklist_free(0, NULL, pud);
 }
 #define __pud_free_tlb(tlb, pud)       pud_free(pud)
 #endif /* CONFIG_PGTABLE_4 */
@@ -112,12 +59,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       return pgtable_quicklist_alloc();
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
 }
 
 static inline void pmd_free(pmd_t * pmd)
 {
-       pgtable_quicklist_free(pmd);
+       quicklist_free(0, NULL, pmd);
 }
 
 #define __pmd_free_tlb(tlb, pmd)       pmd_free(pmd)
@@ -137,28 +84,31 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
 static inline struct page *pte_alloc_one(struct mm_struct *mm,
                                         unsigned long addr)
 {
-       void *pg = pgtable_quicklist_alloc();
+       void *pg = quicklist_alloc(0, GFP_KERNEL, NULL);
        return pg ? virt_to_page(pg) : NULL;
 }
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
                                          unsigned long addr)
 {
-       return pgtable_quicklist_alloc();
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
 }
 
 static inline void pte_free(struct page *pte)
 {
-       pgtable_quicklist_free(page_address(pte));
+       quicklist_free_page(0, NULL, pte);
 }
 
 static inline void pte_free_kernel(pte_t * pte)
 {
-       pgtable_quicklist_free(pte);
+       quicklist_free(0, NULL, pte);
 }
 
-#define __pte_free_tlb(tlb, pte)       pte_free(pte)
+static inline void check_pgt_cache(void)
+{
+       quicklist_trim(0, NULL, 25, 16);
+}
 
-extern void check_pgt_cache(void);
+#define __pte_free_tlb(tlb, pte)       pte_free(pte)
 
 #endif                         /* _ASM_IA64_PGALLOC_H */
index 861c8ec87b095374c942b593ba91b3108d86c79a..f049bc40ca7d5378ce878ff7063c70dce9733e2a 100644 (file)
 #define __NR_vmsplice                  1302
 /* 1303 reserved for move_pages */
 #define __NR_getcpu                    1304
+#define __NR_epoll_pwait               1305
+#define __NR_utimensat                 1306
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls                    281 /* length of syscall table */
+#define NR_syscalls                    283 /* length of syscall table */
 
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
index 0e8da684ce6851d94c88ad492ace3669eaf3c480..aa83d41630965400af10535b4a29b2ce724a40bc 100644 (file)
 #define I2C_DRIVERID_ISL1208   88      /* Intersil ISL1208 RTC         */
 #define I2C_DRIVERID_WM8731            89      /* Wolfson WM8731 audio codec */
 #define I2C_DRIVERID_WM8750            90      /* Wolfson WM8750 audio codec */
+#define I2C_DRIVERID_WM8753            91      /* Wolfson WM8753 audio codec */
 
 #define I2C_DRIVERID_I2CDEV    900
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
index 7906d750aa77481ab34bd5d1c80a9f9db27d38a4..27d936279574dc946fe461dcdb7246aca124a08b 100644 (file)
@@ -140,7 +140,6 @@ enum {
 
        ATA_DFLAG_PIO           = (1 << 8), /* device limited to PIO mode */
        ATA_DFLAG_NCQ_OFF       = (1 << 9), /* device limited to non-NCQ mode */
-       ATA_DFLAG_SUSPENDED     = (1 << 10), /* device suspended */
        ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 16),
@@ -191,6 +190,7 @@ enum {
        ATA_PFLAG_LOADING       = (1 << 4), /* boot/loading probe */
        ATA_PFLAG_UNLOADING     = (1 << 5), /* module is unloading */
        ATA_PFLAG_SCSI_HOTPLUG  = (1 << 6), /* SCSI hotplug scheduled */
+       ATA_PFLAG_INITIALIZING  = (1 << 7), /* being initialized, don't touch */
 
        ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
        ATA_PFLAG_SUSPENDED     = (1 << 17), /* port is suspended (power) */
@@ -254,10 +254,6 @@ enum {
        ATA_DMA_PAD_SZ          = 4,
        ATA_DMA_PAD_BUF_SZ      = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
 
-       /* masks for port functions */
-       ATA_PORT_PRIMARY        = (1 << 0),
-       ATA_PORT_SECONDARY      = (1 << 1),
-
        /* ering size */
        ATA_ERING_SIZE          = 32,
 
@@ -268,13 +264,9 @@ enum {
        ATA_EH_REVALIDATE       = (1 << 0),
        ATA_EH_SOFTRESET        = (1 << 1),
        ATA_EH_HARDRESET        = (1 << 2),
-       ATA_EH_SUSPEND          = (1 << 3),
-       ATA_EH_RESUME           = (1 << 4),
-       ATA_EH_PM_FREEZE        = (1 << 5),
 
        ATA_EH_RESET_MASK       = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
-       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
-                                 ATA_EH_RESUME | ATA_EH_PM_FREEZE,
+       ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
 
        /* ata_eh_info->flags */
        ATA_EHI_HOTPLUGGED      = (1 << 0),  /* could have been hotplugged */
@@ -466,7 +458,7 @@ struct ata_device {
        struct ata_ering        ering;
        int                     spdn_cnt;
        unsigned int            horkage;        /* List of broken features */
-#ifdef CONFIG_SATA_ACPI
+#ifdef CONFIG_ATA_ACPI
        /* ACPI objects info */
        acpi_handle obj_handle;
 #endif
@@ -693,8 +685,8 @@ extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
-extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
-                            unsigned int n_ports);
+extern int ata_pci_init_one (struct pci_dev *pdev,
+                            const struct ata_port_info * const * ppi);
 extern void ata_pci_remove_one (struct pci_dev *pdev);
 #ifdef CONFIG_PM
 extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
@@ -736,8 +728,6 @@ extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val);
 extern int ata_port_online(struct ata_port *ap);
 extern int ata_port_offline(struct ata_port *ap);
 #ifdef CONFIG_PM
-extern int ata_scsi_device_resume(struct scsi_device *);
-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
 extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
 extern void ata_host_resume(struct ata_host *host);
 #endif
@@ -861,11 +851,11 @@ struct pci_bits {
        unsigned long           val;
 };
 
-extern int ata_pci_init_native_host(struct ata_host *host,
-                                   unsigned int port_mask);
+extern int ata_pci_init_native_host(struct ata_host *host);
+extern int ata_pci_init_bmdma(struct ata_host *host);
 extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
                                const struct ata_port_info * const * ppi,
-                               int n_ports, struct ata_host **r_host);
+                               struct ata_host **r_host);
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
 extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
@@ -1008,11 +998,6 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
        return ata_class_absent(dev->class);
 }
 
-static inline unsigned int ata_dev_ready(const struct ata_device *dev)
-{
-       return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
-}
-
 /*
  * port helpers
  */
index ae849f0d443058b1a094d434b26ab9df80b4540f..ccd85e4d3b8fe0bdd19b0f537db73bedae2e6c9c 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP600_SATA  0x4380
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
+#define PCI_DEVICE_ID_ATI_IXP700_SATA  0x4390
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_VLSI_82C592      0x0005
index 796bcf151a3abf3061b9c6fae3eec2ada0f68063..d3f4f5a38214bd31cee806b424faa97065b76bab 100644 (file)
@@ -58,6 +58,7 @@ struct saa7146_pgtable {
        unsigned long   offset;
        /* used for custom pagetables (used for example by budget dvb cards) */
        struct scatterlist *slist;
+       int             nents;
 };
 
 struct saa7146_pci_extension_data {
@@ -157,6 +158,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
 void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
 int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
 char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt);
 void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
 int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop);
 
index 50e33b0e934984c543651bf4cb1fd8b3af550c87..cce20ed5cf6c221ab61360f05436fd399067d698 100644 (file)
@@ -216,6 +216,8 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
 extern struct saa7146_use_ops saa7146_video_uops;
 int saa7146_start_preview(struct saa7146_fh *fh);
 int saa7146_stop_preview(struct saa7146_fh *fh);
+int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, void *arg);
 
 /* from saa7146_vbi.c */
 extern struct saa7146_use_ops saa7146_vbi_uops;
index c149d3b2558b35bfa957ed7c42992471ca8da87a..d647dae912b9fcd3be483c0493b43b3f1f14b158 100644 (file)
@@ -73,7 +73,7 @@
 
 /* AK4114_REQ_FORMAT bits */
 #define AK4114_MONO            (1<<7)  /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */
-#define AK4114_DIF2            (1<<5)  /* Audio Data Control */
+#define AK4114_DIF2            (1<<6)  /* Audio Data Control */
 #define AK4114_DIF1            (1<<5)  /* Audio Data Control */
 #define AK4114_DIF0            (1<<4)  /* Audio Data Control */
 #define AK4114_DIF_16R         (0)                             /* STDO: 16-bit, right justified */
 #define AK4114_CHECK_NO_STAT   (1<<0)  /* no statistics */
 #define AK4114_CHECK_NO_RATE   (1<<1)  /* no rate check */
 
-#define AK4114_CONTROLS                14
+#define AK4114_CONTROLS                15
 
 typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
 typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);
index 8c88267e9beaaa7aa5f95e843703c4a3ad7fcc67..d5c1396c4c9ea974286074d273ae485ffb263ff2 100644 (file)
@@ -50,6 +50,7 @@
 #define MPU401_INFO_INTEGRATED (1 << 2)        /* integrated h/w port */
 #define MPU401_INFO_MMIO       (1 << 3)        /* MMIO access */
 #define MPU401_INFO_TX_IRQ     (1 << 4)        /* independent TX irq */
+#define MPU401_INFO_UART_ONLY  (1 << 5)        /* No ENTER_UART cmd needed */
 
 #define MPU401_MODE_BIT_INPUT          0
 #define MPU401_MODE_BIT_OUTPUT         1
index deff5a92efa6886ecd1d227b534e53fe98c04095..73334e0f823f57d88ae4bbb5eade93b2b008acfa 100644 (file)
@@ -603,11 +603,8 @@ do { \
        read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
 } while (0)
 
-#define snd_pcm_group_for_each(pos, substream) \
-       list_for_each(pos, &substream->group->substreams)
-
-#define snd_pcm_group_substream_entry(pos) \
-       list_entry(pos, struct snd_pcm_substream, link_list)
+#define snd_pcm_group_for_each_entry(s, substream) \
+       list_for_each_entry(s, &substream->group->substreams, link_list)
 
 static inline int snd_pcm_running(struct snd_pcm_substream *substream)
 {
index 42a18cc95f38cdec90b4c94880ed2a058677fa4b..e820f0e7bdd32b807375a64fbf0110994632df14 100644 (file)
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
-#define CONFIG_SND_VERSION "1.0.14rc3"
-#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.14rc4"
+#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"
index ddde0ef9ccdcbb4dbd8834accc5f0264deee8403..b4f1674fca7987d8f99fa707eb2655cd20f0bc37 100644 (file)
@@ -27,6 +27,10 @@ static int irq_affinity_read_proc(char *page, char **start, off_t off,
        return len;
 }
 
+#ifndef is_affinity_mask_valid
+#define is_affinity_mask_valid(val) 1
+#endif
+
 int no_irq_affinity;
 static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
                                   unsigned long count, void *data)
@@ -42,6 +46,9 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
        if (err)
                return err;
 
+       if (!is_affinity_mask_valid(new_value))
+               return -EINVAL;
+
        /*
         * Do not allow disabling IRQs completely - it's a too easy
         * way to make the system unusable accidentally :-) At least
index e91f9f66f3957f3689aba3ae1e8c31a511ad20f9..ded516717940b1d1cba175775cde0ea6aea3a16f 100644 (file)
@@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter,
        onyx->i2c.driver = &onyx_driver;
        onyx->i2c.adapter = adapter;
        onyx->i2c.addr = addr & 0x7f;
-       strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
+       strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);
 
        if (i2c_attach_client(&onyx->i2c)) {
                printk(KERN_ERR PFX "failed to attach to i2c\n");
@@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter,
                goto fail;
        }
 
-       strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
+       strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
        onyx->codec.owner = THIS_MODULE;
        onyx->codec.init = onyx_init_codec;
        onyx->codec.exit = onyx_exit_codec;
index 041fe52cbf2987ce6dfcc2daff3def22bd044c6b..2f771f57c76fbf4207c173b4146bb575fa292cab 100644 (file)
@@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter,
        tas->i2c.addr = addr;
        /* seems that half is a saner default */
        tas->drc_range = TAS3004_DRC_MAX / 2;
-       strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
+       strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE);
 
        if (i2c_attach_client(&tas->i2c)) {
                printk(KERN_ERR PFX "failed to attach to i2c\n");
                goto fail;
        }
 
-       strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
+       strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
        tas->codec.owner = THIS_MODULE;
        tas->codec.init = tas_init_codec;
        tas->codec.exit = tas_exit_codec;
index 8b2e9b905cda8271f15355baeff04364cf3fc564..64d1639143359cc85d93d0b2740bf86d62e6e830 100644 (file)
@@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev)
 
 #endif /* CONFIG_PM */
 
-extern struct device_attribute soundbus_dev_attrs[];
-
 static struct bus_type soundbus_bus_type = {
        .name           = "aoa-soundbus",
        .probe          = soundbus_probe,
index 0fccdbf5166341d78ad0064a4268d38f9c6e6a02..efb9441b3acf2e48deb8543bb4467d4c3cb72a9f 100644 (file)
@@ -23,9 +23,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
 MODULE_DESCRIPTION("Apple Soundbus: I2S support");
-/* for auto-loading, declare that we handle this weird
- * string that macio puts into the relevant device */
-MODULE_ALIAS("of:Ni2sTi2sC");
 
 static int force;
 module_param(force, int, 0444);
@@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = {
        { }
 };
 
+MODULE_DEVICE_TABLE(of, i2sbus_match);
+
 static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
                                       struct dbdma_command_mem *r,
                                       int numcmds)
index 5c27297835d763b052429835813e588cd0f6786c..622cd37a011817f3a4edd94cca5bf12a78faa281 100644 (file)
@@ -199,4 +199,6 @@ struct soundbus_driver {
 extern int soundbus_register_driver(struct soundbus_driver *drv);
 extern void soundbus_unregister_driver(struct soundbus_driver *drv);
 
+extern struct device_attribute soundbus_dev_attrs[];
+
 #endif /* __SOUNDBUS_H */
index 905234817c891d8c2cb0f2446416386aafac1fcc..a96733a5beb88aa6cdd556d7c2f19d8797f0bd51 100644 (file)
@@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops,
                                struct snd_pcm_substream *substream,
                                int state, int do_lock)
 {
-       struct list_head *pos;
        struct snd_pcm_substream *s = NULL;
        struct snd_pcm_substream *s1;
        int res = 0;
 
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                if (do_lock && s != substream)
-                       spin_lock(&s->self_group.lock);
+                       spin_lock_nested(&s->self_group.lock,
+                                        SINGLE_DEPTH_NESTING);
                res = ops->pre_action(s, state);
                if (res < 0)
                        goto _unlock;
        }
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                res = ops->do_action(s, state);
                if (res < 0) {
                        if (ops->undo_action) {
-                               snd_pcm_group_for_each(pos, substream) {
-                                       s1 = snd_pcm_group_substream_entry(pos);
+                               snd_pcm_group_for_each_entry(s1, substream) {
                                        if (s1 == s) /* failed stream */
                                                break;
                                        ops->undo_action(s1, state);
@@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops,
                        goto _unlock;
                }
        }
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                ops->post_action(s, state);
        }
  _unlock:
        if (do_lock) {
                /* unlock streams */
-               snd_pcm_group_for_each(pos, substream) {
-                       s1 = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s1, substream) {
                        if (s1 != substream)
                                spin_unlock(&s1->self_group.lock);
                        if (s1 == s)    /* end */
@@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
 {
        struct snd_card *card;
        struct snd_pcm_runtime *runtime;
-       struct list_head *pos;
+       struct snd_pcm_substream *s;
        int result = 0;
        int i, num_drecs;
        struct drain_rec *drec, drec_tmp, *d;
@@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
 
        /* count only playback streams */
        num_drecs = 0;
-       snd_pcm_group_for_each(pos, substream) {
-               struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                runtime = s->runtime;
                if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                        d = &drec[num_drecs++];
@@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream)
 
 static int snd_pcm_unlink(struct snd_pcm_substream *substream)
 {
-       struct list_head *pos;
+       struct snd_pcm_substream *s;
        int res = 0;
 
        down_write(&snd_pcm_link_rwsem);
@@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
        list_del(&substream->link_list);
        substream->group->count--;
        if (substream->group->count == 1) {     /* detach the last stream, too */
-               snd_pcm_group_for_each(pos, substream) {
-                       relink_to_local(snd_pcm_group_substream_entry(pos));
+               snd_pcm_group_for_each_entry(s, substream) {
+                       relink_to_local(s);
                        break;
                }
                kfree(substream->group);
index 9f7b32e1ccdeb29a7122aaea0f485a0dafa144c5..7cd5e8f5d4cebc2375f7303ce00d48e09046fd96 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/log2.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 
@@ -129,7 +130,7 @@ static int __init rtctimer_init(void)
        struct snd_timer *timer;
 
        if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
-           (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+           !is_power_of_2(rtctimer_freq)) {
                snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
                           rtctimer_freq);
                return -EINVAL;
index 2de181ad0b0506719626a9f74396f45411f3785f..1d563e515c177035daa9fad2ee0342902867535e 100644 (file)
@@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;    /* MPU-401 port number */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;       /* MPU-401 IRQ */
+static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
@@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444);
 MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
 module_param_array(irq, int, NULL, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
+module_param_array(uart_enter, bool, NULL, 0444);
+MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
 static int pnp_registered;
@@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
                strcat(card->longname, "polled");
        }
 
-       if ((err = snd_mpu401_uart_new(card, 0,
-                                      MPU401_HW_MPU401,
-                                      port[dev], 0,
-                                      irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) {
+       err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev],
+                                 uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY,
+                                 irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
+                                 NULL);
+       if (err < 0) {
                printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
                goto _err;
        }
index 3daa9fa56c0bbbc5567c241c7e098ff41b8132a3..85aedc348e2d331b0392e080a2b9d27fbf81f599 100644 (file)
@@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
        return 0;
 }
 
+static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
+{
+       if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
+               return -EIO;
+       if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) &&
+           snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+               return -EIO;
+       return 0;
+}
+
 /*
  * input/output open/close - protected by open_mutex in rawmidi.c
  */
@@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
        if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
                return err;
        if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
-               if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
-                       goto error_out;
-               if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+               if (snd_mpu401_do_reset(mpu) < 0)
                        goto error_out;
        }
        mpu->substream_input = substream;
@@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
        if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
                return err;
        if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
-               if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
-                       goto error_out;
-               if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+               if (snd_mpu401_do_reset(mpu) < 0)
                        goto error_out;
        }
        mpu->substream_output = substream;
index 6c9f4c9bfeb6c3616063daf1b8fe127a65360f17..ebb1bdac7237ca6443d4cba916179515b806e084 100644 (file)
@@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p)
        struct platform_device *device;
 
        device = platform_device_alloc(PLATFORM_DRIVER, device_count);
-       if (!device) 
+       if (!device)
                return;
 
        /* Temporary assignment to forward the parport */
        platform_set_drvdata(device, p);
 
-       if (platform_device_register(device) < 0) {
+       if (platform_device_add(device) < 0) {
                platform_device_put(device);
                return;
        }
index b2d0ba4bd184073ad5b07fa2a2f25a7c81d1cc1a..497cafb57d9b6ec0b16dbadc03775e82009fa88a 100644 (file)
@@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p)
        struct platform_device *device;
 
        device = platform_device_alloc(PLATFORM_DRIVER, device_count);
-       if (!device) 
+       if (!device)
                return;
 
        /* Temporary assignment to forward the parport */
        platform_set_drvdata(device, p);
 
-       if (platform_device_register(device) < 0) {
+       if (platform_device_add(device) < 0) {
                platform_device_put(device);
                return;
        }
index e1920af4501de5b94f6a0808589271445d5942e3..9a8154c9416ed11c8dda6c1a38e695aca7aa25a5 100644 (file)
 
 #ifdef SND_VX_FW_LOADER
 
+MODULE_FIRMWARE("vx/bx_1_vxp.b56");
+MODULE_FIRMWARE("vx/bx_1_vp4.b56");
+MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
+MODULE_FIRMWARE("vx/x1_2_v22.xlx");
+MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
+MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
+MODULE_FIRMWARE("vx/bd56002.boot");
+MODULE_FIRMWARE("vx/bd563v2.boot");
+MODULE_FIRMWARE("vx/bd563s3.boot");
+MODULE_FIRMWARE("vx/l_1_vx2.d56");
+MODULE_FIRMWARE("vx/l_1_v22.d56");
+MODULE_FIRMWARE("vx/l_1_vxp.d56");
+MODULE_FIRMWARE("vx/l_1_vp4.d56");
+
 int snd_vx_setup_firmware(struct vx_core *chip)
 {
        static char *fw_files[VX_TYPE_NUMS][4] = {
index adbfd5884d0606cfce7547fc2757681ab2df746b..1efb973137a60789ad7dc150048987d2808005fd 100644 (file)
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
 #define AK4114_ADDR                    0x00 /* fixed address */
 
 static void ak4114_stats(struct work_struct *work);
+static void ak4114_init_regs(struct ak4114 *chip);
 
 static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
 {
@@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card,
        for (reg = 0; reg < 5; reg++)
                chip->txcsb[reg] = txcsb[reg];
 
-       snd_ak4114_reinit(chip);
+       ak4114_init_regs(chip);
 
        chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
        chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
@@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char
                          (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
 }
 
-void snd_ak4114_reinit(struct ak4114 *chip)
+static void ak4114_init_regs(struct ak4114 *chip)
 {
        unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
 
-       chip->init = 1;
-       mb();
-       flush_scheduled_work();
        /* bring the chip to reset state and powerdown state */
        reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN));
        udelay(200);
@@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip)
                reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]);
        /* release powerdown, everything is initialized now */
        reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN);
+}
+
+void snd_ak4114_reinit(struct ak4114 *chip)
+{
+       chip->init = 1;
+       mb();
+       flush_scheduled_work();
+       ak4114_init_regs(chip);
        /* bring up statistics / event queing */
        chip->init = 0;
-       schedule_delayed_work(&chip->work, HZ / 10);
+       if (chip->kctls[0])
+               schedule_delayed_work(&chip->work, HZ / 10);
 }
 
 static unsigned int external_rate(unsigned char rcs1)
@@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
        .info =         snd_ak4114_in_bit_info,
        .get =          snd_ak4114_in_bit_get,
-       .private_value = (6<<8) | AK4114_REG_RCS1,
+       .private_value = (6<<8) | AK4114_REG_RCS0,
 },
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
        .info =         snd_ak4114_in_bit_info,
        .get =          snd_ak4114_in_bit_get,
-       .private_value = (3<<8) | AK4114_REG_RCS1,
+       .private_value = (3<<8) | AK4114_REG_RCS0,
+},
+{
+       .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+       .name =         "IEC958 PPL Lock Status",
+       .access =       SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+       .info =         snd_ak4114_in_bit_info,
+       .get =          snd_ak4114_in_bit_get,
+       .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0,
 }
 };
 
@@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114,
                kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);
                if (kctl == NULL)
                        return -ENOMEM;
-               if (!strstr(kctl->id.name, "Playback")) {
+               if (strstr(kctl->id.name, "Playback")) {
                        if (ply_substream == NULL) {
                                snd_ctl_free_one(kctl);
                                ak4114->kctls[idx] = NULL;
@@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114,
                        return err;
                ak4114->kctls[idx] = kctl;
        }
+       /* trigger workq */
+       schedule_delayed_work(&ak4114->work, HZ / 10);
        return 0;
 }
 
+/* notify kcontrols if any parameters are changed */
+static void ak4114_notify(struct ak4114 *ak4114,
+                         unsigned char rcs0, unsigned char rcs1,
+                         unsigned char c0, unsigned char c1)
+{
+       if (!ak4114->kctls[0])
+               return;
+
+       if (rcs0 & AK4114_PAR)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[0]->id);
+       if (rcs0 & AK4114_V)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[1]->id);
+       if (rcs1 & AK4114_CCRC)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[2]->id);
+       if (rcs1 & AK4114_QCRC)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[3]->id);
+
+       /* rate change */
+       if (c1 & 0xf0)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[4]->id);
+
+       if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[9]->id);
+       if (c0 & AK4114_QINT)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[10]->id);
+
+       if (c0 & AK4114_AUDION)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[11]->id);
+       if (c0 & AK4114_AUTO)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[12]->id);
+       if (c0 & AK4114_DTSCD)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[13]->id);
+       if (c0 & AK4114_UNLCK)
+               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+                              &ak4114->kctls[14]->id);
+}
+
 int snd_ak4114_external_rate(struct ak4114 *ak4114)
 {
        unsigned char rcs1;
@@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
        ak4114->rcs1 = rcs1;
        spin_unlock_irqrestore(&ak4114->lock, _flags);
 
-       if (rcs0 & AK4114_PAR)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);
-       if (rcs0 & AK4114_V)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);
-       if (rcs1 & AK4114_CCRC)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);
-       if (rcs1 & AK4114_QCRC)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);
-
-       /* rate change */
-       if (c1 & 0xf0)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);
-
-       if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);
-       if (c0 & AK4114_QINT)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);
-
-       if (c0 & AK4114_AUDION)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);
-       if (c0 & AK4114_AUTO)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);
-       if (c0 & AK4114_DTSCD)
-               snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);
-
+       ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
        if (ak4114->change_callback && (c0 | c1) != 0)
                ak4114->change_callback(ak4114, c0, c1);
 
@@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work)
 {
        struct ak4114 *chip = container_of(work, struct ak4114, work.work);
 
-       if (chip->init)
-               return;
-       snd_ak4114_check_rate_and_errors(chip, 0);
+       if (!chip->init)
+               snd_ak4114_check_rate_and_errors(chip, 0);
+
        schedule_delayed_work(&chip->work, HZ / 10);
 }
 
index 4e3a9729f56968d7f3077c27228068521af89536..cf3803cd579cab497e055f57bdfd4f8af5bb892b 100644 (file)
@@ -358,12 +358,21 @@ config SND_SBAWE
 config SND_SB16_CSP
        bool "Sound Blaster 16/AWE CSP support"
        depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
-       select FW_LOADER
+       select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL
        help
          Say Y here to include support for the CSP core.  This special
          coprocessor can do variable tasks like various compression and
          decompression algorithms.
 
+config SND_SB16_CSP_FIRMWARE_IN_KERNEL
+       bool "In-kernel firmware for SB16 CSP"
+       depends on SND_SB16_CSP
+       default y
+       help
+         Say Y here to include the static firmware built in the kernel
+         for the SB16 CSP controller.  If you choose N here, you need
+         to install the firmware files from the alsa-firmware package.
+
 config SND_SGALAXY
        tristate "Aztech Sound Galaxy"
        depends on SND
@@ -391,7 +400,7 @@ config SND_SSCAPE
 config SND_WAVEFRONT
        tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
        depends on SND
-       select FW_LOADER
+       select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL
        select SND_OPL3_LIB
        select SND_MPU401_UART
        select SND_CS4231_LIB
@@ -402,4 +411,13 @@ config SND_WAVEFRONT
          To compile this driver as a module, choose M here: the module
          will be called snd-wavefront.
 
+config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+       bool "In-kernel firmware for Wavefront"
+       depends on SND_WAVEFRONT
+       default y
+       help
+         Say Y here to include the static firmware built in the kernel
+         for the Wavefront driver.  If you choose N here, you need to
+         install the firmware files from the alsa-firmware package.
+
 endmenu
index 59034507175b617b331c1dad07028344813e8f57..fc88a31da6f51a6730d75e6c2cd2e058ac5d1781 100644 (file)
@@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
        }
        acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
        if (acard->devmpu == NULL) {
-               kfree(cfg);
-               return -EBUSY;
+               mpu_port[dev] = -1;
+               snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
        }
 
        pdev = acard->dev;
@@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
        dma2[dev] = pnp_dma(pdev, 1);
        irq[dev] = pnp_irq(pdev, 0);
 
+       if (acard->devmpu == NULL) {
+               kfree(cfg);
+               return 0;
+       }
        pdev = acard->devmpu;
        pnp_init_resource_table(cfg);
 
index 74e501dea8b1f935141f38a0b77cea08d7a8f125..d09a7fa86545d80709330e9d92cd5a23672ab595 100644 (file)
@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
 #include <sound/ad1848.h>
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic AD1848/AD1847/CS4248"
+#define DEV_NAME "ad1848"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("AD1848/AD1847/CS4248");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
                "{Analog Devices,AD1847},"
@@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;   /* 0,1,3,5,6,7 */
 static int thinkpad[SNDRV_CARDS];                      /* Thinkpad special case */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for AD1848 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for AD1848 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable AD1848 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for AD1848 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
+{
+       if (!enable[n])
+               return 0;
 
+       if (port[n] == SNDRV_AUTO_PORT) {
+               snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+               return 0;
+       }
+       if (irq[n] == SNDRV_AUTO_IRQ) {
+               snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+               return 0;       
+       }
+       if (dma1[n] == SNDRV_AUTO_DMA) {
+               snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+               return 0;
+       }
+       return 1;
+}
 
-static int __devinit snd_ad1848_probe(struct platform_device *pdev)
+static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
 {
-       int dev = pdev->id;
        struct snd_card *card;
        struct snd_ad1848 *chip;
        struct snd_pcm *pcm;
-       int err;
+       int error;
 
-       if (port[dev] == SNDRV_AUTO_PORT) {
-               snd_printk(KERN_ERR "ad1848: specify port\n");
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+       if (!card)
                return -EINVAL;
-       }
-       if (irq[dev] == SNDRV_AUTO_IRQ) {
-               snd_printk(KERN_ERR "ad1848: specify irq\n");
-               return -EINVAL;
-       }
-       if (dma1[dev] == SNDRV_AUTO_DMA) {
-               snd_printk(KERN_ERR "ad1848: specify dma1\n");
-               return -EINVAL;
-       }
 
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
+       error = snd_ad1848_create(card, port[n], irq[n], dma1[n],
+                       thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip);
+       if (error < 0)
+               goto out;
 
-       if ((err = snd_ad1848_create(card, port[dev],
-                                    irq[dev],
-                                    dma1[dev],
-                                    thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
-                                    &chip)) < 0)
-               goto _err;
        card->private_data = chip;
 
-       if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
-               goto _err;
+       error = snd_ad1848_pcm(chip, 0, &pcm);
+       if (error < 0)
+               goto out;
 
-       if ((err = snd_ad1848_mixer(chip)) < 0)
-               goto _err;
+       error = snd_ad1848_mixer(chip);
+       if (error < 0)
+               goto out;
 
        strcpy(card->driver, "AD1848");
        strcpy(card->shortname, pcm->name);
 
        sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-               pcm->name, chip->port, irq[dev], dma1[dev]);
-
-       if (thinkpad[dev])
+               pcm->name, chip->port, irq[n], dma1[n]);
+       if (thinkpad[n])
                strcat(card->longname, " [Thinkpad]");
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, dev);
 
-       if ((err = snd_card_register(card)) < 0)
-               goto _err;
+       error = snd_card_register(card);
+       if (error < 0)
+               goto out;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(dev, card);
        return 0;
 
- _err:
-       snd_card_free(card);
-       return err;
+out:   snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_ad1848_remove(struct platform_device *devptr)
+static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
 {
-       struct snd_card *card = platform_get_drvdata(pdev);
+       struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ad1848 *chip = card->private_data;
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
        return 0;
 }
 
-static int snd_ad1848_resume(struct platform_device *pdev)
+static int snd_ad1848_resume(struct device *dev, unsigned int n)
 {
-       struct snd_card *card = platform_get_drvdata(pdev);
+       struct snd_card *card = dev_get_drvdata(dev);
        struct snd_ad1848 *chip = card->private_data;
 
        chip->resume(chip);
@@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev)
 }
 #endif
 
-#define SND_AD1848_DRIVER      "snd_ad1848"
-
-static struct platform_driver snd_ad1848_driver = {
+static struct isa_driver snd_ad1848_driver = {
+       .match          = snd_ad1848_match,
        .probe          = snd_ad1848_probe,
        .remove         = __devexit_p(snd_ad1848_remove),
 #ifdef CONFIG_PM
@@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = {
        .resume         = snd_ad1848_resume,
 #endif
        .driver         = {
-               .name   = SND_AD1848_DRIVER
-       },
+               .name   = DEV_NAME
+       }
 };
 
-static void __init_or_module snd_ad1848_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_ad1848_driver);
-}
-
 static int __init alsa_card_ad1848_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_ad1848_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(SND_AD1848_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
-#endif
-               snd_ad1848_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_ad1848_exit(void)
 {
-       snd_ad1848_unregister_all();
+       isa_unregister_driver(&snd_ad1848_driver);
 }
 
-module_init(alsa_card_ad1848_init)
-module_exit(alsa_card_ad1848_exit)
+module_init(alsa_card_ad1848_init);
+module_exit(alsa_card_ad1848_exit);
index 1124344ed948b38005041306e322d8107a7af4d1..d68720724c91903cd593452e74c81029d6097317 100644 (file)
@@ -5,13 +5,13 @@
 #include <sound/driver.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/opl3.h>
 
 #define CRD_NAME "AdLib FM"
-#define DRV_NAME "snd_adlib"
+#define DEV_NAME "adlib"
 
 MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Rene Herman");
@@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
+{
+       if (!enable[n])
+               return 0;
+
+       if (port[n] == SNDRV_AUTO_PORT) {
+               snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+               return 0;
+       }
+       return 1;
+}
 
 static void snd_adlib_free(struct snd_card *card)
 {
        release_and_free_resource(card->private_data);
 }
 
-static int __devinit snd_adlib_probe(struct platform_device *device)
+static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
 {
        struct snd_card *card;
        struct snd_opl3 *opl3;
+       int error;
 
-       int error, i = device->id;
-
-       if (port[i] == SNDRV_AUTO_PORT) {
-               snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
-               error = -EINVAL;
-               goto out0;
-       }
-
-       card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
        if (!card) {
-               snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
-               error = -EINVAL;
-               goto out0;
+               snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id);
+               return -EINVAL;
        }
 
-       card->private_data = request_region(port[i], 4, CRD_NAME);
+       card->private_data = request_region(port[n], 4, CRD_NAME);
        if (!card->private_data) {
-               snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
+               snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id);
                error = -EBUSY;
-               goto out1;
+               goto out;
        }
        card->private_free = snd_adlib_free;
 
-       error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3);
+       strcpy(card->driver, DEV_NAME);
+       strcpy(card->shortname, CRD_NAME);
+       sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
+
+       error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
        if (error < 0) {
-               snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
-               goto out1;
+               snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id);
+               goto out;
        }
 
        error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
        if (error < 0) {
-               snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
-               goto out1;
+               snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id);
+               goto out;
        }
 
-       strcpy(card->driver, DRV_NAME);
-       strcpy(card->shortname, CRD_NAME);
-       sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
-
-       snd_card_set_dev(card, &device->dev);
+       snd_card_set_dev(card, dev);
 
        error = snd_card_register(card);
        if (error < 0) {
-               snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
-               goto out1;
+               snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id);
+               goto out;
        }
 
-       platform_set_drvdata(device, card);
+       dev_set_drvdata(dev, card);
        return 0;
 
-out1:  snd_card_free(card);
-out0:  return error;
+out  snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_adlib_remove(struct platform_device *device)
+static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(device));
-       platform_set_drvdata(device, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
-static struct platform_driver snd_adlib_driver = {
+static struct isa_driver snd_adlib_driver = {
+       .match          = snd_adlib_match,
        .probe          = snd_adlib_probe,
        .remove         = __devexit_p(snd_adlib_remove),
 
        .driver         = {
-               .name   = DRV_NAME
+               .name   = DEV_NAME
        }
 };
 
 static int __init alsa_card_adlib_init(void)
 {
-       int i, cards;
-
-       if (platform_driver_register(&snd_adlib_driver) < 0) {
-               snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
-               return -ENODEV;
-       }
-
-       for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-
-               if (!enable[i])
-                       continue;
-
-               device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-
-               devices[i] = device;
-               cards++;
-       }
-
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
-#endif
-               platform_driver_unregister(&snd_adlib_driver);
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_adlib_exit(void)
 {
-       int i;
-
-       for (i = 0; i < SNDRV_CARDS; i++)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_adlib_driver);
+       isa_unregister_driver(&snd_adlib_driver);
 }
 
 module_init(alsa_card_adlib_init);
index c09a8009d2fa7230196a27fab89231dcfcc4fb7b..214d65d94c4538541af52fdc6be4dc00d35ab7c3 100644 (file)
@@ -46,7 +46,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver.");
 module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 #endif
@@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
        return snd_card_register(card);
 }
 
-static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cmi8330_isa_match(struct device *pdev,
+                                          unsigned int dev)
 {
-       struct snd_card *card;
-       int err;
-       int dev = pdev->id;
-
+       if (!enable[dev] || is_isapnp_selected(dev))
+               return 0;
        if (wssport[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify wssport\n");
-               return -EINVAL;
+               return 0;
        }
        if (sbport[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify sbport\n");
-               return -EINVAL;
+               return 0;
        }
+       return 1;
+}
+
+static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
+                                          unsigned int dev)
+{
+       struct snd_card *card;
+       int err;
 
        card = snd_cmi8330_card_new(dev);
        if (! card)
                return -ENOMEM;
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
        if ((err = snd_cmi8330_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
-static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
+                                           unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
+                                  pm_message_t state)
 {
-       return snd_cmi8330_suspend(platform_get_drvdata(dev));
+       return snd_cmi8330_suspend(dev_get_drvdata(dev));
 }
 
-static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
+static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
 {
-       return snd_cmi8330_resume(platform_get_drvdata(dev));
+       return snd_cmi8330_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define CMI8330_DRIVER "snd_cmi8330"
+#define DEV_NAME       "cmi8330"
 
-static struct platform_driver snd_cmi8330_driver = {
-       .probe          = snd_cmi8330_nonpnp_probe,
-       .remove         = __devexit_p(snd_cmi8330_nonpnp_remove),
+static struct isa_driver snd_cmi8330_driver = {
+       .match          = snd_cmi8330_isa_match,
+       .probe          = snd_cmi8330_isa_probe,
+       .remove         = __devexit_p(snd_cmi8330_isa_remove),
 #ifdef CONFIG_PM
-       .suspend        = snd_cmi8330_nonpnp_suspend,
-       .resume         = snd_cmi8330_nonpnp_resume,
+       .suspend        = snd_cmi8330_isa_suspend,
+       .resume         = snd_cmi8330_isa_resume,
 #endif
        .driver         = {
-               .name   = CMI8330_DRIVER
+               .name   = DEV_NAME
        },
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata cmi8330_pnp_devices;
-
 static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
                                            const struct pnp_card_device_id *pid)
 {
@@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
        }
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       cmi8330_pnp_devices++;
        return 0;
 }
 
@@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_cmi8330_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnp_registered)
-               pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_cmi8330_driver);
-}
-
 static int __init alsa_card_cmi8330_init(void)
 {
-       int i, err, cards = 0;
+       int err;
 
-       if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
+       err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i] || is_isapnp_selected(i))
-                       continue;
-               device = platform_device_register_simple(CMI8330_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               cards++;
-       }
-
 #ifdef CONFIG_PNP
        err = pnp_register_card_driver(&cmi8330_pnpc_driver);
-       if (!err) {
+       if (!err)
                pnp_registered = 1;
-               cards += cmi8330_pnp_devices;
-       }
 #endif
-
-       if (!cards) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
-#endif
-               snd_cmi8330_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_cmi8330_exit(void)
 {
-       snd_cmi8330_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnp_registered)
+               pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+#endif
+       isa_unregister_driver(&snd_cmi8330_driver);
 }
 
 module_init(alsa_card_cmi8330_init)
index 696a5c86bcfae7c60f51e1e4dfd01355f7ff9283..ac40411341502ace9f4c9c047b8fe882b4c954aa 100644 (file)
@@ -23,7 +23,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
 #include <sound/mpu401.h>
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic CS4231"
+#define DEV_NAME "cs4231"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Generic CS4231");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
 
@@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;      /* 0,1,3,5,6,7 */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CS4231 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CS4231 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS4231 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for CS4231 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
+{
+       if (!enable[n])
+               return 0;
 
+       if (port[n] == SNDRV_AUTO_PORT) {
+               snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+               return 0;
+       }
+       if (irq[n] == SNDRV_AUTO_IRQ) {
+               snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+               return 0;
+       }
+       if (dma1[n] == SNDRV_AUTO_DMA) {
+               snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+               return 0;
+       }
+       return 1;
+}
 
-static int __init snd_cs4231_probe(struct platform_device *pdev)
+static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
 {
-       int dev = pdev->id;
        struct snd_card *card;
-       struct snd_pcm *pcm;
        struct snd_cs4231 *chip;
-       int err;
+       struct snd_pcm *pcm;
+       int error;
 
-       if (port[dev] == SNDRV_AUTO_PORT) {
-               snd_printk(KERN_ERR "specify port\n");
-               return -EINVAL;
-       }
-       if (irq[dev] == SNDRV_AUTO_IRQ) {
-               snd_printk(KERN_ERR "specify irq\n");
-               return -EINVAL;
-       }
-       if (dma1[dev] == SNDRV_AUTO_DMA) {
-               snd_printk(KERN_ERR "specify dma1\n");
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+       if (!card)
                return -EINVAL;
-       }
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
-       if ((err = snd_cs4231_create(card, port[dev], -1,
-                                    irq[dev],
-                                    dma1[dev],
-                                    dma2[dev],
-                                    CS4231_HW_DETECT,
-                                    0, &chip)) < 0)
-               goto _err;
+
+       error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
+                       CS4231_HW_DETECT, 0, &chip);
+       if (error < 0)
+               goto out;
+
        card->private_data = chip;
 
-       if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
-               goto _err;
+       error = snd_cs4231_pcm(chip, 0, &pcm);
+       if (error < 0)
+               goto out;
 
        strcpy(card->driver, "CS4231");
        strcpy(card->shortname, pcm->name);
+
        sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-               pcm->name, chip->port, irq[dev], dma1[dev]);
-       if (dma2[dev] >= 0)
-               sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
-
-       if ((err = snd_cs4231_mixer(chip)) < 0)
-               goto _err;
-       if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
-               goto _err;
-
-       if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
-               if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
-                       mpu_irq[dev] = -1;
+               pcm->name, chip->port, irq[n], dma1[n]);
+       if (dma2[n] >= 0)
+               sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
+
+       error = snd_cs4231_mixer(chip);
+       if (error < 0)
+               goto out;
+
+       error = snd_cs4231_timer(chip, 0, NULL);
+       if (error < 0)
+               goto out;
+
+       if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
+               if (mpu_irq[n] == SNDRV_AUTO_IRQ)
+                       mpu_irq[n] = -1;
                if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
-                                       mpu_port[dev], 0,
-                                       mpu_irq[dev],
-                                       mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
+                                       mpu_port[n], 0, mpu_irq[n],
+                                       mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
                                        NULL) < 0)
-                       printk(KERN_WARNING "cs4231: MPU401 not detected\n");
+                       printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id);
        }
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, dev);
 
-       if ((err = snd_card_register(card)) < 0)
-               goto _err;
+       error = snd_card_register(card);
+       if (error < 0)
+               goto out;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(dev, card);
        return 0;
 
- _err:
-       snd_card_free(card);
-       return err;
+out:   snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_cs4231_remove(struct platform_device *devptr)
+static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
 {
-       struct snd_card *card;
-       struct snd_cs4231 *chip;
-       card = platform_get_drvdata(dev);
+       struct snd_card *card = dev_get_drvdata(dev);
+       struct snd_cs4231 *chip = card->private_data;
+
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-       chip = card->private_data;
        chip->suspend(chip);
        return 0;
 }
 
-static int snd_cs4231_resume(struct platform_device *dev)
+static int snd_cs4231_resume(struct device *dev, unsigned int n)
 {
-       struct snd_card *card;
-       struct snd_cs4231 *chip;
-       card = platform_get_drvdata(dev);
-       chip = card->private_data;
+       struct snd_card *card = dev_get_drvdata(dev);
+       struct snd_cs4231 *chip = card->private_data;
+
        chip->resume(chip);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }
 #endif
 
-#define SND_CS4231_DRIVER      "snd_cs4231"
-
-static struct platform_driver snd_cs4231_driver = {
+static struct isa_driver snd_cs4231_driver = {
+       .match          = snd_cs4231_match,
        .probe          = snd_cs4231_probe,
        .remove         = __devexit_p(snd_cs4231_remove),
 #ifdef CONFIG_PM
@@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = {
        .resume         = snd_cs4231_resume,
 #endif
        .driver         = {
-               .name   = SND_CS4231_DRIVER
-       },
+               .name   = DEV_NAME
+       }
 };
 
-static void __init_or_module snd_cs4231_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_cs4231_driver);
-}
-
 static int __init alsa_card_cs4231_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_cs4231_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(SND_CS4231_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "CS4231 soundcard not found or device busy\n");
-#endif
-               snd_cs4231_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_cs4231_exit(void)
 {
-       snd_cs4231_unregister_all();
+       isa_unregister_driver(&snd_cs4231_driver);
 }
 
-module_init(alsa_card_cs4231_init)
-module_exit(alsa_card_cs4231_exit)
+module_init(alsa_card_cs4231_init);
+module_exit(alsa_card_cs4231_exit);
index 75c7c5f01989a478dd664aa58a7b503e22b0c478..914d77b61b0c042d865b22cb7b78fa09e44f3b20 100644 (file)
@@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
        struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
        int result = 0;
        unsigned int what;
-       struct list_head *pos;
        struct snd_pcm_substream *s;
        int do_start;
 
@@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
        }
 
        what = 0;
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                if (s == chip->playback_substream) {
                        what |= CS4231_PLAYBACK_ENABLE;
                        snd_pcm_trigger_done(s, substream);
index 07ffd5c22e81918eeb0c7647f3e19428f7832c99..87f1392a2fa79f4310e6ced4e3829070af372840 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
 
 #ifdef CS4232
 #define IDENT "CS4232"
-#define CS423X_DRIVER "snd_cs4232"
+#define DEV_NAME "cs4232"
 #else
 #define IDENT "CS4236+"
-#define CS423X_DRIVER "snd_cs4236"
+#define DEV_NAME "cs4236"
 #endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
@@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnpc_registered;
 #ifdef CS4232
 static int pnp_registered;
 #endif
 #endif /* CONFIG_PNP */
-static unsigned int snd_cs423x_devices;
 
 struct snd_card_cs4236 {
        struct snd_cs4231 *chip;
@@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
        return snd_card_register(card);
 }
 
-static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cs423x_isa_match(struct device *pdev,
+                                         unsigned int dev)
 {
-       int dev = pdev->id;
-       struct snd_card *card;
-       int err;
+       if (!enable[dev] || is_isapnp_selected(dev))
+               return 0;
 
        if (port[dev] == SNDRV_AUTO_PORT) {
-               snd_printk(KERN_ERR "specify port\n");
-               return -EINVAL;
+               snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id);
+               return 0;
        }
        if (cport[dev] == SNDRV_AUTO_PORT) {
-               snd_printk(KERN_ERR "specify cport\n");
-               return -EINVAL;
+               snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id);
+               return 0;
+       }
+       if (irq[dev] == SNDRV_AUTO_IRQ) {
+               snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+               return 0;
        }
+       if (dma1[dev] == SNDRV_AUTO_DMA) {
+               snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id);
+               return 0;
+       }
+       return 1;
+}
+
+static int __devinit snd_cs423x_isa_probe(struct device *pdev,
+                                         unsigned int dev)
+{
+       struct snd_card *card;
+       int err;
 
        card = snd_cs423x_card_new(dev);
        if (! card)
                return -ENOMEM;
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
        if ((err = snd_cs423x_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
-static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cs423x_isa_remove(struct device *pdev,
+                                          unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(pdev));
+       dev_set_drvdata(pdev, NULL);
        return 0;
 }
 
@@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card)
        return 0;
 }
 
-static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n,
+                                 pm_message_t state)
 {
-       return snd_cs423x_suspend(platform_get_drvdata(dev));
+       return snd_cs423x_suspend(dev_get_drvdata(dev));
 }
 
-static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
+static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
 {
-       return snd_cs423x_resume(platform_get_drvdata(dev));
+       return snd_cs423x_resume(dev_get_drvdata(dev));
 }
 #endif
 
-static struct platform_driver cs423x_nonpnp_driver = {
-       .probe          = snd_cs423x_nonpnp_probe,
-       .remove         = __devexit_p(snd_cs423x_nonpnp_remove),
+static struct isa_driver cs423x_isa_driver = {
+       .match          = snd_cs423x_isa_match,
+       .probe          = snd_cs423x_isa_probe,
+       .remove         = __devexit_p(snd_cs423x_isa_remove),
 #ifdef CONFIG_PM
-       .suspend        = snd_cs423x_nonpnp_suspend,
-       .resume         = snd_cs423x_nonpnp_resume,
+       .suspend        = snd_cs423x_isa_suspend,
+       .resume         = snd_cs423x_isa_resume,
 #endif
        .driver         = {
-               .name   = CS423X_DRIVER
+               .name   = DEV_NAME
        },
 };
 
@@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
        }
        pnp_set_drvdata(pdev, card);
        dev++;
-       snd_cs423x_devices++;
        return 0;
 }
 
@@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
        }
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       snd_cs423x_devices++;
        return 0;
 }
 
@@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_cs423x_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnpc_registered)
-               pnp_unregister_card_driver(&cs423x_pnpc_driver);
-#ifdef CS4232
-       if (pnp_registered)
-               pnp_unregister_driver(&cs4232_pnp_driver);
-#endif
-#endif /* CONFIG_PNP */
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&cs423x_nonpnp_driver);
-}
-
 static int __init alsa_card_cs423x_init(void)
 {
-       int i, err;
+       int err;
 
-       if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
+       err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i] || is_isapnp_selected(i))
-                       continue;
-               device = platform_device_register_simple(CS423X_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               snd_cs423x_devices++;
-       }
 #ifdef CONFIG_PNP
 #ifdef CS4232
        err = pnp_register_driver(&cs4232_pnp_driver);
@@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void)
        if (!err)
                pnpc_registered = 1;
 #endif /* CONFIG_PNP */
-
-       if (!snd_cs423x_devices) {
-#ifdef MODULE
-               printk(KERN_ERR IDENT " soundcard not found or device busy\n");
-#endif
-               snd_cs423x_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_cs423x_exit(void)
 {
-       snd_cs423x_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnpc_registered)
+               pnp_unregister_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+       if (pnp_registered)
+               pnp_unregister_driver(&cs4232_pnp_driver);
+#endif
+#endif /* CONFIG_PNP */
+       isa_unregister_driver(&cs423x_isa_driver);
 }
 
 module_init(alsa_card_cs423x_init)
index 65f97ff4eef1e747d7ba5bb0a1d6f875415cad13..edc398712e8be53438ee650c35b04a119c611852 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive"
+#define DEV_NAME "es1688"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("ESS ESx688 AudioDrive");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
                "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
@@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;      /* 5,7,9,10 */
 static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;      /* 0,1,3 */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ESx688 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ESx688 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ESx688 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for ESx688 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
-
-static struct platform_device *devices[SNDRV_CARDS];
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
 
-#define PFX    "es1688: "
+static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
+{
+       return enable[n];
+}
 
-static int __devinit snd_es1688_probe(struct platform_device *pdev)
+static int __devinit snd_es1688_legacy_create(struct snd_card *card, 
+               struct device *dev, unsigned int n, struct snd_es1688 **rchip)
 {
-       int dev = pdev->id;
+       static long possible_ports[] = {0x220, 0x240, 0x260};
        static int possible_irqs[] = {5, 9, 10, 7, -1};
        static int possible_dmas[] = {1, 3, 0, -1};
-       int xirq, xdma, xmpu_irq;
-       struct snd_card *card;
-       struct snd_es1688 *chip;
-       struct snd_opl3 *opl3;
-       struct snd_pcm *pcm;
-       int err;
-
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
-
-       xirq = irq[dev];
-       if (xirq == SNDRV_AUTO_IRQ) {
-               if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-                       err = -EBUSY;
-                       goto _err;
+
+       int i, error;
+
+       if (irq[n] == SNDRV_AUTO_IRQ) {
+               irq[n] = snd_legacy_find_free_irq(possible_irqs);
+               if (irq[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+                               dev->bus_id);
+                       return -EBUSY;
                }
        }
-       xmpu_irq = mpu_irq[dev];
-       xdma = dma8[dev];
-       if (xdma == SNDRV_AUTO_DMA) {
-               if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
-                       err = -EBUSY;
-                       goto _err;
+       if (dma8[n] == SNDRV_AUTO_DMA) {
+               dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+               if (dma8[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free DMA\n",
+                               dev->bus_id);
+                       return -EBUSY;
                }
        }
 
-       if (port[dev] != SNDRV_AUTO_PORT) {
-               if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
-                                            xirq, xmpu_irq, xdma,
-                                            ES1688_HW_AUTO, &chip)) < 0)
-                       goto _err;
-       } else {
-               /* auto-probe legacy ports */
-               static unsigned long possible_ports[] = {
-                       0x220, 0x240, 0x260,
-               };
-               int i;
-               for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-                       err = snd_es1688_create(card, possible_ports[i],
-                                               mpu_port[dev],
-                                               xirq, xmpu_irq, xdma,
-                                               ES1688_HW_AUTO, &chip);
-                       if (err >= 0) {
-                               port[dev] = possible_ports[i];
-                               break;
-                       }
-               }
-               if (i >= ARRAY_SIZE(possible_ports))
-                       goto _err;
-       }
+       if (port[n] != SNDRV_AUTO_PORT)
+               return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+                               mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+
+       i = 0;
+       do {
+               port[n] = possible_ports[i];
+               error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+                               mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+       } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
+
+       return error;
+}
+
+static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
+{
+       struct snd_card *card;
+       struct snd_es1688 *chip;
+       struct snd_opl3 *opl3;
+       struct snd_pcm *pcm;
+       int error;
+
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+       if (!card)
+               return -EINVAL;
+
+       error = snd_es1688_legacy_create(card, dev, n, &chip);
+       if (error < 0)
+               goto out;
 
-       if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
-               goto _err;
+       error = snd_es1688_pcm(chip, 0, &pcm);
+       if (error < 0)
+               goto out;
 
-       if ((err = snd_es1688_mixer(chip)) < 0)
-               goto _err;
+       error = snd_es1688_mixer(chip);
+       if (error < 0)
+               goto out;
 
        strcpy(card->driver, "ES1688");
        strcpy(card->shortname, pcm->name);
-       sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
-
-       if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
-               printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
-       } else {
-               if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
-                       goto _err;
+       sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
+               chip->port, chip->irq, chip->dma8);
+
+       if (snd_opl3_create(card, chip->port, chip->port + 2,
+                       OPL3_HW_OPL3, 0, &opl3) < 0)
+               printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n",
+                       dev->bus_id, chip->port);
+       else {
+               error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+               if (error < 0)
+                       goto out;
        }
 
-       if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
-               if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
-                                              chip->mpu_port, 0,
-                                              xmpu_irq,
-                                              IRQF_DISABLED,
-                                              NULL)) < 0)
-                       goto _err;
+       if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
+                       chip->mpu_port > 0) {
+               error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+                               chip->mpu_port, 0,
+                               mpu_irq[n], IRQF_DISABLED, NULL);
+               if (error < 0)
+                       goto out;
        }
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, dev);
 
-       if ((err = snd_card_register(card)) < 0)
-               goto _err;
+       error = snd_card_register(card);
+       if (error < 0)
+               goto out;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(dev, card);
        return 0;
 
- _err:
-       snd_card_free(card);
-       return err;
+out:   snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_es1688_remove(struct platform_device *devptr)
+static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
-#define ES1688_DRIVER  "snd_es1688"
-
-static struct platform_driver snd_es1688_driver = {
+static struct isa_driver snd_es1688_driver = {
+       .match          = snd_es1688_match,
        .probe          = snd_es1688_probe,
-       .remove         = __devexit_p(snd_es1688_remove),
-       /* FIXME: suspend/resume */
+       .remove         = snd_es1688_remove,
+#if 0  /* FIXME */
+       .suspend        = snd_es1688_suspend,
+       .resume         = snd_es1688_resume,
+#endif
        .driver         = {
-               .name   = ES1688_DRIVER
-       },
+               .name   = DEV_NAME
+       }
 };
 
-static void __init_or_module snd_es1688_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_es1688_driver);
-}
-
 static int __init alsa_card_es1688_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_es1688_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(ES1688_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
-#endif
-               snd_es1688_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_es1688_exit(void)
 {
-       snd_es1688_unregister_all();
+       isa_unregister_driver(&snd_es1688_driver);
 }
 
-module_init(alsa_card_es1688_init)
-module_exit(alsa_card_es1688_exit)
+module_init(alsa_card_es1688_init);
+module_exit(alsa_card_es1688_exit);
index 725c115ff97da3277723d54903081afbc41a84d5..d2a9c7df0ce5100a6a6cc4a9caaa5260d97f1202 100644 (file)
@@ -80,7 +80,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
@@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
 #ifdef CONFIG_PNP
 static int pnp_registered, pnpc_registered;
 
@@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
        return snd_card_register(card);
 }
 
-static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
+{
+       return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
 {
        struct snd_card *card;
        int err;
@@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d
        card = snd_es18xx_card_new(dev);
        if (! card)
                return -ENOMEM;
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
        if ((err = snd_audiodrive_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 }
 
-static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
 {
-       int dev = pdev->id;
        int err;
        static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
        static int possible_dmas[] = {1, 0, 3, 5, -1};
@@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
        }
 
        if (port[dev] != SNDRV_AUTO_PORT) {
-               return snd_es18xx_nonpnp_probe1(dev, pdev);
+               return snd_es18xx_isa_probe1(dev, pdev);
        } else {
                static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
                int i;
                for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
                        port[dev] = possible_ports[i];
-                       err = snd_es18xx_nonpnp_probe1(dev, pdev);
+                       err = snd_es18xx_isa_probe1(dev, pdev);
                        if (! err)
                                return 0;
                }
@@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
        }
 }
 
-static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_es18xx_isa_remove(struct device *devptr,
+                                          unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
+                                 pm_message_t state)
 {
-       return snd_es18xx_suspend(platform_get_drvdata(dev), state);
+       return snd_es18xx_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_es18xx_nonpnp_resume(struct platform_device *dev)
+static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
 {
-       return snd_es18xx_resume(platform_get_drvdata(dev));
+       return snd_es18xx_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define ES18XX_DRIVER  "snd_es18xx"
+#define DEV_NAME "es18xx"
 
-static struct platform_driver snd_es18xx_nonpnp_driver = {
-       .probe          = snd_es18xx_nonpnp_probe,
-       .remove         = __devexit_p(snd_es18xx_nonpnp_remove),
+static struct isa_driver snd_es18xx_isa_driver = {
+       .match          = snd_es18xx_isa_match,
+       .probe          = snd_es18xx_isa_probe,
+       .remove         = __devexit_p(snd_es18xx_isa_remove),
 #ifdef CONFIG_PM
-       .suspend        = snd_es18xx_nonpnp_suspend,
-       .resume         = snd_es18xx_nonpnp_resume,
+       .suspend        = snd_es18xx_isa_suspend,
+       .resume         = snd_es18xx_isa_resume,
 #endif
        .driver         = {
-               .name   = ES18XX_DRIVER
+               .name   = DEV_NAME
        },
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata es18xx_pnp_devices;
-
 static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
                                            const struct pnp_device_id *id)
 {
@@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
        }
        pnp_set_drvdata(pdev, card);
        dev++;
-       es18xx_pnp_devices++;
        return 0;
 }
 
@@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
 
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       es18xx_pnp_devices++;
        return 0;
 }
 
@@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_es18xx_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnpc_registered)
-               pnp_unregister_card_driver(&es18xx_pnpc_driver);
-       if (pnp_registered)
-               pnp_unregister_driver(&es18xx_pnp_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_es18xx_nonpnp_driver);
-}
-
 static int __init alsa_card_es18xx_init(void)
 {
-       int i, err, cards = 0;
+       int err;
 
-       if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
+       err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
 
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i] || is_isapnp_selected(i))
-                       continue;
-               device = platform_device_register_simple(ES18XX_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               cards++;
-       }
-
 #ifdef CONFIG_PNP
        err = pnp_register_driver(&es18xx_pnp_driver);
        if (!err)
@@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void)
        err = pnp_register_card_driver(&es18xx_pnpc_driver);
        if (!err)
                pnpc_registered = 1;
-       cards += es18xx_pnp_devices;
-#endif
-
-       if(!cards) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
 #endif
-               snd_es18xx_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_es18xx_exit(void)
 {
-       snd_es18xx_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnpc_registered)
+               pnp_unregister_card_driver(&es18xx_pnpc_driver);
+       if (pnp_registered)
+               pnp_unregister_driver(&es18xx_pnp_driver);
+#endif
+       isa_unregister_driver(&snd_es18xx_isa_driver);
 }
 
 module_init(alsa_card_es18xx_init)
index 0395e2e0dd038290f6bb16dff43944b0acd40cf3..8f23f433d491a9086c51a0005b9b6f3eb1677c01 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Gravis UltraSound Classic"
+#define DEV_NAME "gusclassic"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Classic");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
 
@@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Classic driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
 module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
+{
+       return enable[n];
+}
+
+static int __devinit snd_gusclassic_create(struct snd_card *card,
+               struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+       static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
+       static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
+       static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
+
+       int i, error;
+
+       if (irq[n] == SNDRV_AUTO_IRQ) {
+               irq[n] = snd_legacy_find_free_irq(possible_irqs);
+               if (irq[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+                               dev->bus_id);
+                       return -EBUSY;
+               }
+       }
+       if (dma1[n] == SNDRV_AUTO_DMA) {
+               dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+               if (dma1[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free DMA1\n",
+                               dev->bus_id);
+                       return -EBUSY;
+               }
+       }
+       if (dma2[n] == SNDRV_AUTO_DMA) {
+               dma2[n] = snd_legacy_find_free_dma(possible_dmas);
+               if (dma2[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free DMA2\n",
+                               dev->bus_id);
+                       return -EBUSY;
+               }
+       }
 
-static struct platform_device *devices[SNDRV_CARDS];
+       if (port[n] != SNDRV_AUTO_PORT)
+               return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+                               0, channels[n], pcm_channels[n], 0, rgus);
 
+       i = 0;
+       do {
+               port[n] = possible_ports[i];
+               error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+                               0, channels[n], pcm_channels[n], 0, rgus);
+       } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
 
-#define PFX    "gusclassic: "
+       return error;
+}
 
-static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
+static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
 {
        unsigned char d;
 
@@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
        return 0;
 }
 
-static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus)
-{
-       gus->equal_irq = 0;
-       gus->codec_flag = 0;
-       gus->max_flag = 0;
-       gus->joystick_dac = joystick_dac[dev];
-}
-
-static int __devinit snd_gusclassic_probe(struct platform_device *pdev)
+static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
 {
-       int dev = pdev->id;
-       static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
-       static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
-       int xirq, xdma1, xdma2;
        struct snd_card *card;
-       struct snd_gus_card *gus = NULL;
-       int err;
-
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
-       if (pcm_channels[dev] < 2)
-               pcm_channels[dev] = 2;
-
-       xirq = irq[dev];
-       if (xirq == SNDRV_AUTO_IRQ) {
-               if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-                       err = -EBUSY;
-                       goto _err;
-               }
-       }
-       xdma1 = dma1[dev];
-       if (xdma1 == SNDRV_AUTO_DMA) {
-               if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
-                       err = -EBUSY;
-                       goto _err;
-               }
-       }
-       xdma2 = dma2[dev];
-       if (xdma2 == SNDRV_AUTO_DMA) {
-               if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
-                       err = -EBUSY;
-                       goto _err;
-               }
-       }
+       struct snd_gus_card *gus;
+       int error;
 
-       if (port[dev] != SNDRV_AUTO_PORT) {
-               err = snd_gus_create(card,
-                                    port[dev],
-                                    xirq, xdma1, xdma2,
-                                    0, channels[dev], pcm_channels[dev],
-                                    0, &gus);
-       } else {
-               /* auto-probe legacy ports */
-               static unsigned long possible_ports[] = {
-                       0x220, 0x230, 0x240, 0x250, 0x260,
-               };
-               int i;
-               for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-                       err = snd_gus_create(card,
-                                            possible_ports[i],
-                                            xirq, xdma1, xdma2,
-                                            0, channels[dev], pcm_channels[dev],
-                                            0, &gus);
-                       if (err >= 0) {
-                               port[dev] = possible_ports[i];
-                               break;
-                       }
-               }
-       }
-       if (err < 0)
-               goto _err;
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+       if (!card)
+               return -EINVAL;
 
-       if ((err = snd_gusclassic_detect(gus)) < 0)
-               goto _err;
+       if (pcm_channels[n] < 2)
+               pcm_channels[n] = 2;
 
-       snd_gusclassic_init(dev, gus);
-       if ((err = snd_gus_initialize(gus)) < 0)
-               goto _err;
+       error = snd_gusclassic_create(card, dev, n, &gus);
+       if (error < 0)
+               goto out;
 
+       error = snd_gusclassic_detect(gus);
+       if (error < 0)
+               goto out;
+
+       gus->joystick_dac = joystick_dac[n];
+
+       error = snd_gus_initialize(gus);
+       if (error < 0)
+               goto out;
+
+       error = -ENODEV;
        if (gus->max_flag || gus->ess_flag) {
-               snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
-               err = -ENODEV;
-               goto _err;
+               snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was "
+                       "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
+               goto out;
        }
 
-       if ((err = snd_gf1_new_mixer(gus)) < 0)
-               goto _err;
+       error = snd_gf1_new_mixer(gus);
+       if (error < 0)
+               goto out;
 
-       if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
-               goto _err;
+       error = snd_gf1_pcm_new(gus, 0, 0, NULL);
+       if (error < 0)
+               goto out;
 
        if (!gus->ace_flag) {
-               if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
-                       goto _err;
+               error = snd_gf1_rawmidi_new(gus, 0, NULL);
+               if (error < 0)
+                       goto out;
        }
-       sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
-       if (xdma2 >= 0)
-               sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-       snd_card_set_dev(card, &pdev->dev);
+       sprintf(card->longname + strlen(card->longname),
+               " at 0x%lx, irq %d, dma %d",
+               gus->gf1.port, gus->gf1.irq, gus->gf1.dma1);
 
-       if ((err = snd_card_register(card)) < 0)
-               goto _err;
+       if (gus->gf1.dma2 >= 0)
+               sprintf(card->longname + strlen(card->longname),
+                       "&%d", gus->gf1.dma2);
 
-       platform_set_drvdata(pdev, card);
+       snd_card_set_dev(card, dev);
+
+       error = snd_card_register(card);
+       if (error < 0)
+               goto out;
+
+       dev_set_drvdata(dev, card);
        return 0;
 
- _err:
-       snd_card_free(card);
-       return err;
+out:   snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_gusclassic_remove(struct platform_device *devptr)
+static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
-#define GUSCLASSIC_DRIVER      "snd_gusclassic"
-
-static struct platform_driver snd_gusclassic_driver = {
+static struct isa_driver snd_gusclassic_driver = {
+       .match          = snd_gusclassic_match,
        .probe          = snd_gusclassic_probe,
        .remove         = __devexit_p(snd_gusclassic_remove),
-       /* FIXME: suspend/resume */
+#if 0  /* FIXME */
+       .suspend        = snd_gusclassic_suspend,
+       .remove         = snd_gusclassic_remove,
+#endif
        .driver         = {
-               .name   = GUSCLASSIC_DRIVER
-       },
+               .name   = DEV_NAME
+       }
 };
 
-static void __init_or_module snd_gusclassic_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_gusclassic_driver);
-}
-
 static int __init alsa_card_gusclassic_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_gusclassic_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(GUSCLASSIC_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
-#endif
-               snd_gusclassic_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusclassic_exit(void)
 {
-       snd_gusclassic_unregister_all();
+       isa_unregister_driver(&snd_gusclassic_driver);
 }
 
-module_init(alsa_card_gusclassic_init)
-module_exit(alsa_card_gusclassic_exit)
+module_init(alsa_card_gusclassic_init);
+module_exit(alsa_card_gusclassic_exit);
index 4f55fc3e66c14cc1dd167fe1b60c19693fab6170..0aeaa6cf6cf0409eba067fedfe69c0e87127817f 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Gravis UltraSound Extreme"
+#define DEV_NAME "gusextreme"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Extreme");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
 
@@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Extreme driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(gf1_port, long, NULL, 0444);
-MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional).");
+MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(gf1_irq, int, NULL, 0444);
-MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
 module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
+{
+       return enable[n];
+}
+
+static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
+               struct device *dev, unsigned int n, struct snd_es1688 **rchip)
+{
+       static long possible_ports[] = {0x220, 0x240, 0x260};
+       static int possible_irqs[] = {5, 9, 10, 7, -1};
+       static int possible_dmas[] = {1, 3, 0, -1};
+
+       int i, error;
+
+       if (irq[n] == SNDRV_AUTO_IRQ) {
+               irq[n] = snd_legacy_find_free_irq(possible_irqs);
+               if (irq[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+                               "for ES1688\n", dev->bus_id);
+                       return -EBUSY;
+               }
+       }
+       if (dma8[n] == SNDRV_AUTO_DMA) {
+               dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+               if (dma8[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free DMA "
+                               "for ES1688\n", dev->bus_id);
+                       return -EBUSY;
+               }
+       }
 
-static struct platform_device *devices[SNDRV_CARDS];
+       if (port[n] != SNDRV_AUTO_PORT)
+               return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+                               mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
 
+       i = 0;
+       do {
+               port[n] = possible_ports[i];
+               error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+                               mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
+       } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
 
-#define PFX    "gusextreme: "
+       return error;
+}
 
-static int __devinit snd_gusextreme_detect(int dev,
-                                       struct snd_card *card,
-                                       struct snd_gus_card * gus,
-                                       struct snd_es1688 *es1688)
+static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
+               struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+       static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
+       static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
+
+       if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
+               gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
+               if (gf1_irq[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+                               "for GF1\n", dev->bus_id);
+                       return -EBUSY;
+               }
+       }
+       if (dma1[n] == SNDRV_AUTO_DMA) {
+               dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+               if (dma1[n] < 0) {
+                       snd_printk(KERN_ERR "%s: unable to find a free DMA "
+                               "for GF1\n", dev->bus_id);
+                       return -EBUSY;
+               }
+       }
+       return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1,
+                       0, channels[n], pcm_channels[n], 0, rgus);
+}
+
+static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
+       struct snd_es1688 *es1688)
 {
        unsigned long flags;
        unsigned char d;
@@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev,
        spin_lock_irqsave(&es1688->mixer_lock, flags);
        snd_es1688_mixer_write(es1688, 0x40, 0x0b);     /* don't change!!! */
        spin_unlock_irqrestore(&es1688->mixer_lock, flags);
+
        spin_lock_irqsave(&es1688->reg_lock, flags);
-       outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
+       outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
        outb(0, 0x201);
-       outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
+       outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
        outb(0, 0x201);
-       outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
+       outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
        spin_unlock_irqrestore(&es1688->reg_lock, flags);
 
        udelay(100);
@@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev,
                snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
                return -EIO;
        }
-       return 0;
-}
 
-static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus)
-{
-       gus->joystick_dac = joystick_dac[dev];
+       return 0;
 }
 
 static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip)
 {
        struct snd_card *card = chip->card;
        struct snd_ctl_elem_id id1, id2;
-       int err;
+       int error;
 
        memset(&id1, 0, sizeof(id1));
        memset(&id2, 0, sizeof(id2));
        id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+
        /* reassign AUX to SYNTHESIZER */
        strcpy(id1.name, "Aux Playback Volume");
        strcpy(id2.name, "Synth Playback Volume");
-       if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-               return err;
+       error = snd_ctl_rename_id(card, &id1, &id2);
+       if (error < 0)
+               return error;
+
        /* reassign Master Playback Switch to Synth Playback Switch */
        strcpy(id1.name, "Master Playback Switch");
        strcpy(id2.name, "Synth Playback Switch");
-       if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-               return err;
+       error = snd_ctl_rename_id(card, &id1, &id2);
+       if (error < 0)
+               return error;
+
        return 0;
 }
 
-static int __devinit snd_gusextreme_probe(struct platform_device *pdev)
+static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
 {
-       int dev = pdev->id;
-       static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
-       static int possible_ess_dmas[] = {1, 3, 0, -1};
-       static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
-       static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
-       int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
        struct snd_card *card;
        struct snd_gus_card *gus;
        struct snd_es1688 *es1688;
        struct snd_opl3 *opl3;
-       int err;
+       int error;
 
-       card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-       if (card == NULL)
-               return -ENOMEM;
+       card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+       if (!card)
+               return -EINVAL;
 
-       xgf1_irq = gf1_irq[dev];
-       if (xgf1_irq == SNDRV_AUTO_IRQ) {
-               if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
-                       err = -EBUSY;
-                       goto out;
-               }
-       }
-       xess_irq = irq[dev];
-       if (xess_irq == SNDRV_AUTO_IRQ) {
-               if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
-                       err = -EBUSY;
-                       goto out;
-               }
-       }
-       if (mpu_port[dev] == SNDRV_AUTO_PORT)
-               mpu_port[dev] = 0;
-       xmpu_irq = mpu_irq[dev];
-       if (xmpu_irq > 15)
-               xmpu_irq = -1;
-       xgf1_dma = dma1[dev];
-       if (xgf1_dma == SNDRV_AUTO_DMA) {
-               if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
-                       err = -EBUSY;
-                       goto out;
-               }
-       }
-       xess_dma = dma8[dev];
-       if (xess_dma == SNDRV_AUTO_DMA) {
-               if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
-                       snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
-                       err = -EBUSY;
-                       goto out;
-               }
-       }
+       if (mpu_port[n] == SNDRV_AUTO_PORT)
+               mpu_port[n] = 0;
 
-       if (port[dev] != SNDRV_AUTO_PORT) {
-               err = snd_es1688_create(card, port[dev], mpu_port[dev],
-                                       xess_irq, xmpu_irq, xess_dma,
-                                       ES1688_HW_1688, &es1688);
-       } else {
-               /* auto-probe legacy ports */
-               static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
-               int i;
-               for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-                       err = snd_es1688_create(card,
-                                               possible_ports[i],
-                                               mpu_port[dev],
-                                               xess_irq, xmpu_irq, xess_dma,
-                                               ES1688_HW_1688, &es1688);
-                       if (err >= 0) {
-                               port[dev] = possible_ports[i];
-                               break;
-                       }
-               }
-       }
-       if (err < 0)
+       if (mpu_irq[n] > 15)
+               mpu_irq[n] = -1;
+
+       error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
+       if (error < 0)
                goto out;
 
-       if (gf1_port[dev] < 0)
-               gf1_port[dev] = port[dev] + 0x20;
-       if ((err = snd_gus_create(card,
-                                 gf1_port[dev],
-                                 xgf1_irq,
-                                 xgf1_dma,
-                                 -1,
-                                 0, channels[dev],
-                                 pcm_channels[dev], 0,
-                                 &gus)) < 0)
+       if (gf1_port[n] < 0)
+               gf1_port[n] = es1688->port + 0x20;
+
+       error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
+       if (error < 0)
                goto out;
 
-       if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
+       error = snd_gusextreme_detect(gus, es1688);
+       if (error < 0)
                goto out;
 
-       snd_gusextreme_init(dev, gus);
-       if ((err = snd_gus_initialize(gus)) < 0)
+       gus->joystick_dac = joystick_dac[n];
+
+       error = snd_gus_initialize(gus);
+       if (error < 0)
                goto out;
 
+       error = -ENODEV;
        if (!gus->ess_flag) {
-               snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
-               err = -ENODEV;
+               snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not "
+                       "detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
                goto out;
        }
-       if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
+       gus->codec_flag = 1;
+
+       error = snd_es1688_pcm(es1688, 0, NULL);
+       if (error < 0)
                goto out;
 
-       if ((err = snd_es1688_mixer(es1688)) < 0)
+       error = snd_es1688_mixer(es1688);
+       if (error < 0)
                goto out;
 
        snd_component_add(card, "ES1688");
-       if (pcm_channels[dev] > 0) {
-               if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+
+       if (pcm_channels[n] > 0) {
+               error = snd_gf1_pcm_new(gus, 1, 1, NULL);
+               if (error < 0)
                        goto out;
        }
-       if ((err = snd_gf1_new_mixer(gus)) < 0)
+
+       error = snd_gf1_new_mixer(gus);
+       if (error < 0)
                goto out;
 
-       if ((err = snd_gusextreme_mixer(es1688)) < 0)
+       error = snd_gusextreme_mixer(es1688);
+       if (error < 0)
                goto out;
 
        if (snd_opl3_create(card, es1688->port, es1688->port + 2,
-                           OPL3_HW_OPL3, 0, &opl3) < 0) {
-               printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
-       } else {
-               if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
+                       OPL3_HW_OPL3, 0, &opl3) < 0)
+               printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n",
+                       dev->bus_id, es1688->port);
+       else {
+               error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
+               if (error < 0)
                        goto out;
        }
 
-       if (es1688->mpu_port >= 0x300 &&
-           (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
-                                              es1688->mpu_port, 0,
-                                              xmpu_irq,
-                                              IRQF_DISABLED,
-                                              NULL)) < 0)
-               goto out;
+       if (es1688->mpu_port >= 0x300) {
+               error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+                               es1688->mpu_port, 0,
+                               mpu_irq[n], IRQF_DISABLED, NULL);
+               if (error < 0)
+                       goto out;
+       }
 
-       sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
-               es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
+       sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
+               "irq %i&%i, dma %i&%i", es1688->port,
+               gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, dev);
 
-       if ((err = snd_card_register(card)) < 0)
+       error = snd_card_register(card);
+       if (error < 0)
                goto out;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(dev, card);
        return 0;
 
-      out:
-       snd_card_free(card);
-       return err;
+out:   snd_card_free(card);
+       return error;
 }
 
-static int __devexit snd_gusextreme_remove(struct platform_device *devptr)
+static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(dev));
+       dev_set_drvdata(dev, NULL);
        return 0;
 }
 
-#define GUSEXTREME_DRIVER      "snd_gusextreme"
-
-static struct platform_driver snd_gusextreme_driver = {
+static struct isa_driver snd_gusextreme_driver = {
+       .match          = snd_gusextreme_match,
        .probe          = snd_gusextreme_probe,
-       .remove         = __devexit_p(snd_gusextreme_remove),
-       /* FIXME: suspend/resume */
+       .remove         = snd_gusextreme_remove,
+#if 0  /* FIXME */
+       .suspend        = snd_gusextreme_suspend,
+       .resume         = snd_gusextreme_resume,
+#endif
        .driver         = {
-               .name   = GUSEXTREME_DRIVER
-       },
+               .name   = DEV_NAME
+       }
 };
 
-static void __init_or_module snd_gusextreme_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_gusextreme_driver);
-}
-
 static int __init alsa_card_gusextreme_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_gusextreme_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(GUSEXTREME_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
-#endif
-               snd_gusextreme_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusextreme_exit(void)
 {
-       snd_gusextreme_unregister_all();
+       isa_unregister_driver(&snd_gusextreme_driver);
 }
 
-module_init(alsa_card_gusextreme_init)
-module_exit(alsa_card_gusextreme_exit)
+module_init(alsa_card_gusextreme_init);
+module_exit(alsa_card_gusextreme_exit);
index d1ad90ca035de59760b9b500aa139372e0b47586..708783d4351fa8317482b86c06717b716ea3c1cc 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 struct snd_gusmax {
        int irq;
        struct snd_card *card;
@@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card)
                free_irq(maxcard->irq, (void *)maxcard);
 }
 
-static int __devinit snd_gusmax_probe(struct platform_device *pdev)
+static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
+{
+       return enable[dev];
+}
+
+static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
 {
-       int dev = pdev->id;
        static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
        static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
        int xirq, xdma1, xdma2, err;
@@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
        if (xdma2 >= 0)
                sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
 
        if ((err = snd_card_register(card)) < 0)
                goto _err;
@@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
        maxcard->gus = gus;
        maxcard->cs4231 = cs4231;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 
  _err:
@@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
        return err;
 }
 
-static int __devexit snd_gusmax_remove(struct platform_device *devptr)
+static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-#define GUSMAX_DRIVER  "snd_gusmax"
+#define DEV_NAME "gusmax"
 
-static struct platform_driver snd_gusmax_driver = {
+static struct isa_driver snd_gusmax_driver = {
+       .match          = snd_gusmax_match,
        .probe          = snd_gusmax_probe,
        .remove         = __devexit_p(snd_gusmax_remove),
        /* FIXME: suspend/resume */
        .driver         = {
-               .name   = GUSMAX_DRIVER
+               .name   = DEV_NAME
        },
 };
 
-static void __init_or_module snd_gusmax_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_gusmax_driver);
-}
-
 static int __init alsa_card_gusmax_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_gusmax_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(GUSMAX_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "GUS MAX soundcard not found or device busy\n");
-#endif
-               snd_gusmax_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusmax_exit(void)
 {
-       snd_gusmax_unregister_all();
+       isa_unregister_driver(&snd_gusmax_driver);
 }
 
 module_init(alsa_card_gusmax_init)
index 4ec2d79431fc1b1ca8cd335fca51c330ec9222c7..3e46572555361d48fd7331de7a9996f574be37e2 100644 (file)
@@ -25,7 +25,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
@@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
 module_param_array(effect, int, NULL, 0444);
 MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-
 struct snd_interwave {
        int irq;
        struct snd_card *card;
@@ -138,6 +135,7 @@ struct snd_interwave {
 
 
 #ifdef CONFIG_PNP
+static int pnp_registered;
 
 static struct pnp_card_device_id snd_interwave_pnpids[] = {
 #ifndef SNDRV_STB
@@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
        return 0;
 }
 
-static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
 {
        struct snd_card *card;
        int err;
@@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device
        if (! card)
                return -ENOMEM;
 
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
        if ((err = snd_interwave_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 }
 
-static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_interwave_isa_match(struct device *pdev,
+                                            unsigned int dev)
+{
+       if (!enable[dev])
+               return 0;
+#ifdef CONFIG_PNP
+       if (isapnp[dev])
+               return 0;
+#endif
+       return 1;
+}
+
+static int __devinit snd_interwave_isa_probe(struct device *pdev,
+                                            unsigned int dev)
 {
-       int dev = pdev->id;
        int err;
        static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
        static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
@@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
        }
 
        if (port[dev] != SNDRV_AUTO_PORT)
-               return snd_interwave_nonpnp_probe1(dev, pdev);
+               return snd_interwave_isa_probe1(dev, pdev);
        else {
                static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
                int i;
                for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
                        port[dev] = possible_ports[i];
-                       err = snd_interwave_nonpnp_probe1(dev, pdev);
+                       err = snd_interwave_isa_probe1(dev, pdev);
                        if (! err)
                                return 0;
                }
@@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
        }
 }
 
-static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-static struct platform_driver snd_interwave_driver = {
-       .probe          = snd_interwave_nonpnp_probe,
-       .remove         = __devexit_p(snd_interwave_nonpnp_remove),
+static struct isa_driver snd_interwave_driver = {
+       .match          = snd_interwave_isa_match,
+       .probe          = snd_interwave_isa_probe,
+       .remove         = __devexit_p(snd_interwave_isa_remove),
        /* FIXME: suspend,resume */
        .driver         = {
                .name   = INTERWAVE_DRIVER
@@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = {
 };
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata interwave_pnp_devices;
-
 static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
                                              const struct pnp_card_device_id *pid)
 {
@@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
        }
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       interwave_pnp_devices++;
        return 0;
 }
 
@@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_interwave_unregister_all(void)
-{
-       int i;
-
-       if (pnp_registered)
-               pnp_unregister_card_driver(&interwave_pnpc_driver);
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_interwave_driver);
-}
-
 static int __init alsa_card_interwave_init(void)
 {
-       int i, err, cards = 0;
+       int err;
 
-       if ((err = platform_driver_register(&snd_interwave_driver)) < 0)
+       err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
 #ifdef CONFIG_PNP
-               if (isapnp[i])
-                       continue;
-#endif
-               device = platform_device_register_simple(INTERWAVE_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               cards++;
-       }
-
        /* ISA PnP cards */
        err = pnp_register_card_driver(&interwave_pnpc_driver);
-       if (!err) {
+       if (!err)
                pnp_registered = 1;
-               cards += interwave_pnp_devices;;
-       }
-
-       if (!cards) {
-#ifdef MODULE
-               printk(KERN_ERR "InterWave soundcard not found or device busy\n");
 #endif
-               snd_interwave_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_interwave_exit(void)
 {
-       snd_interwave_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnp_registered)
+               pnp_unregister_card_driver(&interwave_pnpc_driver);
+#endif
+       isa_unregister_driver(&snd_interwave_driver);
 }
 
 module_init(alsa_card_interwave_init)
index f3db686b1c0c5da850bfeda7bb790e59df9d8cf6..48743eb85fb64cf2b3a8650dfdbf7b7f6056f10b 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 static int pnpc_registered;
 #endif
-static unsigned int snd_opl3sa2_devices;
 
 /* control ports */
 #define OPL3SA2_PM_CTRL                0x01
@@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
        }
        pnp_set_drvdata(pdev, card);
        dev++;
-       snd_opl3sa2_devices++;
        return 0;
 }
 
@@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
        }
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       snd_opl3sa2_devices++;
        return 0;
 }
 
@@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
+                                          unsigned int dev)
 {
-       struct snd_card *card;
-       int err;
-       int dev = pdev->id;
-
+       if (!enable[dev])
+               return 0;
+#ifdef CONFIG_PNP
+       if (isapnp[dev])
+               return 0;
+#endif
        if (port[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify port\n");
-               return -EINVAL;
+               return 0;
        }
        if (wss_port[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify wss_port\n");
-               return -EINVAL;
+               return 0;
        }
        if (fm_port[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify fm_port\n");
-               return -EINVAL;
+               return 0;
        }
        if (midi_port[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify midi_port\n");
-               return -EINVAL;
+               return 0;
        }
+       return 1;
+}
+
+static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
+                                          unsigned int dev)
+{
+       struct snd_card *card;
+       int err;
 
        card = snd_opl3sa2_card_new(dev);
        if (! card)
                return -ENOMEM;
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
        if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
-static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
+                                           unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
+                                  pm_message_t state)
 {
-       return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
+       return snd_opl3sa2_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
+static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
 {
-       return snd_opl3sa2_resume(platform_get_drvdata(dev));
+       return snd_opl3sa2_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define OPL3SA2_DRIVER "snd_opl3sa2"
+#define DEV_NAME "opl3sa2"
 
-static struct platform_driver snd_opl3sa2_nonpnp_driver = {
-       .probe          = snd_opl3sa2_nonpnp_probe,
-       .remove         = __devexit( snd_opl3sa2_nonpnp_remove),
+static struct isa_driver snd_opl3sa2_isa_driver = {
+       .match          = snd_opl3sa2_isa_match,
+       .probe          = snd_opl3sa2_isa_probe,
+       .remove         = __devexit( snd_opl3sa2_isa_remove),
 #ifdef CONFIG_PM
-       .suspend        = snd_opl3sa2_nonpnp_suspend,
-       .resume         = snd_opl3sa2_nonpnp_resume,
+       .suspend        = snd_opl3sa2_isa_suspend,
+       .resume         = snd_opl3sa2_isa_resume,
 #endif
        .driver         = {
-               .name   = OPL3SA2_DRIVER
+               .name   = DEV_NAME
        },
 };
 
-static void __init_or_module snd_opl3sa2_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnpc_registered)
-               pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-       if (pnp_registered)
-               pnp_unregister_driver(&opl3sa2_pnp_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-}
-
 static int __init alsa_card_opl3sa2_init(void)
 {
-       int i, err;
+       int err;
 
-       if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
+       err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-#ifdef CONFIG_PNP
-               if (isapnp[i])
-                       continue;
-#endif
-               device = platform_device_register_simple(OPL3SA2_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               snd_opl3sa2_devices++;
-       }
-
 #ifdef CONFIG_PNP
        err = pnp_register_driver(&opl3sa2_pnp_driver);
        if (!err)
@@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void)
        if (!err)
                pnpc_registered = 1;
 #endif
-
-       if (!snd_opl3sa2_devices) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
-#endif
-               snd_opl3sa2_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
 {
-       snd_opl3sa2_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnpc_registered)
+               pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+       if (pnp_registered)
+               pnp_unregister_driver(&opl3sa2_pnp_driver);
+#endif
+       isa_unregister_driver(&snd_opl3sa2_isa_driver);
 }
 
 module_init(alsa_card_opl3sa2_init)
index 1dd98375ac85788f294ec5a7327fcd74ba2720c6..cd29b30b362e4529601a105a5e26a05ca2da6e5a 100644 (file)
@@ -25,7 +25,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
@@ -137,10 +137,6 @@ struct snd_miro {
 
 static void snd_miro_proc_init(struct snd_miro * miro);
 
-#define DRIVER_NAME "snd-miro"
-
-static struct platform_device *device;
-
 static char * snd_opti9xx_names[] = {
        "unkown",
        "82C928", "82C929",
@@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static struct snd_kcontrol_new snd_miro_controls[] = {
+static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
 MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
 MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
 MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
@@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
 
 /* Equalizer with seven bands (only PCM20) 
    from -12dB up to +12dB on each band */
-static struct snd_kcontrol_new snd_miro_eq_controls[] = {
+static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
 MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
 MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
 MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
@@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
 MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
 };
 
-static struct snd_kcontrol_new snd_miro_radio_control[] = {
+static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
 MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_line_control[] = {
+static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
 MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_preamp_control[] = {
+static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
 {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Mic Boost",
@@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = {
        .put = snd_miro_put_preamp,
 }};
 
-static struct snd_kcontrol_new snd_miro_amp_control[] = {
+static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
 {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Line Boost",
@@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = {
        .put = snd_miro_put_amp,
 }};
 
-static struct snd_kcontrol_new snd_miro_capture_control[] = {
+static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
 {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "PCM Capture Switch",
@@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = {
        .put = snd_miro_put_capture,
 }};
 
-static unsigned char aci_init_values[][2] __initdata = {
+static unsigned char aci_init_values[][2] __devinitdata = {
        { ACI_SET_MUTE, 0x00 },
        { ACI_SET_POWERAMP, 0x00 },
        { ACI_SET_PREAMP, 0x00 },
@@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = {
        { ACI_SET_MASTER + 1, 0x20 },
 };
 
-static int __init snd_set_aci_init_values(struct snd_miro *miro)
+static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
 {
        int idx, error;
 
@@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size)
        return -1;
 }
 
-static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware)
+static int __devinit snd_miro_init(struct snd_miro *chip,
+                                  unsigned short hardware)
 {
        static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
        snd_iprintf(buffer, "  preamp  : 0x%x\n", miro->aci_preamp);
 }
 
-static void __init snd_miro_proc_init(struct snd_miro * miro)
+static void __devinit snd_miro_proc_init(struct snd_miro * miro)
 {
        struct snd_info_entry *entry;
 
@@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
  *  Init
  */
 
-static int __init snd_miro_configure(struct snd_miro *chip)
+static int __devinit snd_miro_configure(struct snd_miro *chip)
 {
        unsigned char wss_base_bits;
        unsigned char irq_bits;
@@ -1131,7 +1128,8 @@ __skip_mpu:
        return 0;
 }
 
-static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip)
+static int __devinit snd_card_miro_detect(struct snd_card *card,
+                                         struct snd_miro *chip)
 {
        int i, err;
        unsigned char value;
@@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c
        return -ENODEV;
 }
 
-static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro)
+static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
+                                             struct snd_miro * miro)
 {
        unsigned char regval;
        int i;
@@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card)
        release_and_free_resource(miro->res_mc_base);
 }
 
-static int __init snd_miro_probe(struct platform_device *devptr)
+static int __devinit snd_miro_match(struct device *devptr, unsigned int n)
+{
+       return 1;
+}
+
+static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
 {
        static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
        static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
@@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr)
                 return error;
        }
 
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
 
        if ((error = snd_card_register(card))) {
                snd_card_free(card);
                return error;
        }
 
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 }
 
-static int __devexit snd_miro_remove(struct platform_device *devptr)
+static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-static struct platform_driver snd_miro_driver = {
+#define DEV_NAME "miro"
+
+static struct isa_driver snd_miro_driver = {
+       .match          = snd_miro_match,
        .probe          = snd_miro_probe,
        .remove         = __devexit_p(snd_miro_remove),
        /* FIXME: suspend/resume */
        .driver         = {
-               .name   = DRIVER_NAME
+               .name   = DEV_NAME
        },
 };
 
 static int __init alsa_card_miro_init(void)
 {
-       int error;
-
-       if ((error = platform_driver_register(&snd_miro_driver)) < 0)
-               return error;
-       device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-       if (! IS_ERR(device)) {
-               if (platform_get_drvdata(device))
-                       return 0;
-               platform_device_unregister(device);
-       }
-#ifdef MODULE
-       printk(KERN_ERR "no miro soundcard found\n");
-#endif
-       platform_driver_unregister(&snd_miro_driver);
-       return PTR_ERR(device);
+       return isa_register_driver(&snd_miro_driver, 1);
 }
 
 static void __exit alsa_card_miro_exit(void)
 {
-       platform_device_unregister(device);
-       platform_driver_unregister(&snd_miro_driver);
+       isa_unregister_driver(&snd_miro_driver);
 }
 
 module_init(alsa_card_miro_init)
index df227377c3331d8d46030c3d37bb6bb8d298df65..60c120ffb9de9a664afcfaa26f36a2670823ebba 100644 (file)
@@ -26,7 +26,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
@@ -259,7 +259,6 @@ struct snd_opti9xx {
 };
 
 static int snd_opti9xx_pnp_is_probed;
-static struct platform_device *snd_opti9xx_platform_device;
 
 #ifdef CONFIG_PNP
 
@@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
 #endif /* CONFIG_PNP */
 
 #ifdef OPTi93X
-#define DRIVER_NAME    "snd-card-opti93x"
+#define DEV_NAME "opti93x"
 #else
-#define DRIVER_NAME    "snd-card-opti92x"
-#endif /* OPTi93X */
+#define DEV_NAME "opti92x"
+#endif
 
 static char * snd_opti9xx_names[] = {
        "unkown",
@@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = {
 };
 
 
-static long __init snd_legacy_find_free_ioport(long *port_table, long size)
+static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
 {
        while (*port_table != -1) {
                if (request_region(*port_table, size, "ALSA test")) {
@@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size)
        return -1;
 }
 
-static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
+static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
+                                     unsigned short hardware)
 {
        static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
                (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
 
 
-static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
+static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
 {
        unsigned char wss_base_bits;
        unsigned char irq_bits;
@@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_STOP:
        {
                unsigned int what = 0;
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == chip->playback_substream) {
                                what |= OPTi93X_PLAYBACK_ENABLE;
                                snd_pcm_trigger_done(s, substream);
@@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
        }
        codec->dma2 = chip->dma2;
 
-       if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) {
+       if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
                snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
                snd_opti93x_free(codec);
                return -EBUSY;
@@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
        return change;
 }
 
-static struct snd_kcontrol_new snd_opti93x_controls[] = {
+static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
 OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
 OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), 
 OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
@@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip)
 
 #endif /* OPTi93X */
 
-static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
+static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
+                                            struct snd_opti9xx *chip)
 {
        int i, err;
 
@@ -1676,8 +1675,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti
 }
 
 #ifdef CONFIG_PNP
-static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
-                                      const struct pnp_card_device_id *pid)
+static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
+                                         struct pnp_card_link *card,
+                                         const struct pnp_card_device_id *pid)
 {
        struct pnp_dev *pdev;
        struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
@@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
                release_and_free_resource(chip->res_mc_base);
 }
 
-static int __init snd_opti9xx_probe(struct snd_card *card)
+static int __devinit snd_opti9xx_probe(struct snd_card *card)
 {
        static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
        int error;
@@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void)
        return card;
 }
 
-static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
+static int __devinit snd_opti9xx_isa_match(struct device *devptr,
+                                          unsigned int dev)
+{
+       if (snd_opti9xx_pnp_is_probed)
+               return 0;
+       if (isapnp)
+               return 0;
+       return 1;
+}
+
+static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
+                                          unsigned int dev)
 {
        struct snd_card *card;
        int error;
@@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
        static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
 #endif /* CS4231 || OPTi93X */
 
-       if (snd_opti9xx_pnp_is_probed)
-               return -EBUSY;
-
        if (mpu_port == SNDRV_AUTO_PORT) {
                if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
                        snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
@@ -1984,34 +1992,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
                snd_card_free(card);
                return error;
        }
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
        if ((error = snd_opti9xx_probe(card)) < 0) {
                snd_card_free(card);
                return error;
        }
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 }
 
-static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
+                                           unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-static struct platform_driver snd_opti9xx_driver = {
-       .probe          = snd_opti9xx_nonpnp_probe,
-       .remove         = __devexit_p(snd_opti9xx_nonpnp_remove),
+static struct isa_driver snd_opti9xx_driver = {
+       .match          = snd_opti9xx_isa_match,
+       .probe          = snd_opti9xx_isa_probe,
+       .remove         = __devexit_p(snd_opti9xx_isa_remove),
        /* FIXME: suspend/resume */
        .driver         = {
-               .name   = DRIVER_NAME
+               .name   = DEV_NAME
        },
 };
 
 #ifdef CONFIG_PNP
-static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
-                                       const struct pnp_card_device_id *pid)
+static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+                                          const struct pnp_card_device_id *pid)
 {
        struct snd_card *card;
        int error, hw;
@@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 };
 #endif
 
-#ifdef CONFIG_PNP
-#define is_isapnp_selected()   isapnp
-#else
-#define is_isapnp_selected()   0
-#endif
 #ifdef OPTi93X
 #define CHIP_NAME      "82C93x"
 #else
@@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 
 static int __init alsa_card_opti9xx_init(void)
 {
-       int error;
-       struct platform_device *device;
-
 #ifdef CONFIG_PNP
        pnp_register_card_driver(&opti9xx_pnpc_driver);
        if (snd_opti9xx_pnp_is_probed)
                return 0;
 #endif
-       if (! is_isapnp_selected()) {
-               error = platform_driver_register(&snd_opti9xx_driver);
-               if (error < 0)
-                       return error;
-               device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-               if (!IS_ERR(device)) {
-                       if (platform_get_drvdata(device)) {
-                               snd_opti9xx_platform_device = device;
-                               return 0;
-                       }
-                       platform_device_unregister(device);
-               }
-               platform_driver_unregister(&snd_opti9xx_driver);
-       }
-#ifdef CONFIG_PNP
-       pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-#ifdef MODULE
-       printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
-#endif
-       return -ENODEV;
+       return isa_register_driver(&snd_opti9xx_driver, 1);
 }
 
 static void __exit alsa_card_opti9xx_exit(void)
 {
        if (!snd_opti9xx_pnp_is_probed) {
-               platform_device_unregister(snd_opti9xx_platform_device);
-               platform_driver_unregister(&snd_opti9xx_driver);
+               isa_unregister_driver(&snd_opti9xx_driver);
+               return;
        }
 #ifdef CONFIG_PNP
        pnp_unregister_card_driver(&opti9xx_pnpc_driver);
index d64e67f2bafa3ef2537c03a703ff800d2b6ac8a8..2a19b0a39eda1ff139cabbfc042b5ad6b9d63708 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/sb.h>
@@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444);
 MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
 #endif
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 #endif
@@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card)
 }
 #endif
 
-static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
 {
        struct snd_card_sb16 *acard;
        struct snd_card *card;
@@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev
        awe_port[dev] = port[dev] + 0x400;
 #endif
 
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, pdev);
        if ((err = snd_sb16_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
 
-static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
+{
+       return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
 {
-       int dev = pdev->id;
        int err;
        static int possible_irqs[] = {5, 9, 10, 7, -1};
        static int possible_dmas8[] = {1, 3, 0, -1};
@@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
        }
 
        if (port[dev] != SNDRV_AUTO_PORT)
-               return snd_sb16_nonpnp_probe1(dev, pdev);
+               return snd_sb16_isa_probe1(dev, pdev);
        else {
                static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
                int i;
                for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
                        port[dev] = possible_ports[i];
-                       err = snd_sb16_nonpnp_probe1(dev, pdev);
+                       err = snd_sb16_isa_probe1(dev, pdev);
                        if (! err)
                                return 0;
                }
@@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
        }
 }
 
-static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(pdev));
+       dev_set_drvdata(pdev, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
+                               pm_message_t state)
 {
-       return snd_sb16_suspend(platform_get_drvdata(dev), state);
+       return snd_sb16_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_sb16_nonpnp_resume(struct platform_device *dev)
+static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
 {
-       return snd_sb16_resume(platform_get_drvdata(dev));
+       return snd_sb16_resume(dev_get_drvdata(dev));
 }
 #endif
 
 #ifdef SNDRV_SBAWE
-#define SND_SB16_DRIVER        "snd_sbawe"
+#define DEV_NAME "sbawe"
 #else
-#define SND_SB16_DRIVER        "snd_sb16"
+#define DEV_NAME "sb16"
 #endif
 
-static struct platform_driver snd_sb16_nonpnp_driver = {
-       .probe          = snd_sb16_nonpnp_probe,
-       .remove         = __devexit_p(snd_sb16_nonpnp_remove),
+static struct isa_driver snd_sb16_isa_driver = {
+       .match          = snd_sb16_isa_match,
+       .probe          = snd_sb16_isa_probe,
+       .remove         = __devexit_p(snd_sb16_isa_remove),
 #ifdef CONFIG_PM
-       .suspend        = snd_sb16_nonpnp_suspend,
-       .resume         = snd_sb16_nonpnp_resume,
+       .suspend        = snd_sb16_isa_suspend,
+       .resume         = snd_sb16_isa_resume,
 #endif
        .driver         = {
-               .name   = SND_SB16_DRIVER
+               .name   = DEV_NAME
        },
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata sb16_pnp_devices;
-
 static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
                                         const struct pnp_card_device_id *pid)
 {
@@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
                }
                pnp_set_card_drvdata(pcard, card);
                dev++;
-               sb16_pnp_devices++;
                return 0;
        }
 
@@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_sb16_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnp_registered)
-               pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_sb16_nonpnp_driver);
-}
-
 static int __init alsa_card_sb16_init(void)
 {
-       int i, err, cards = 0;
+       int err;
 
-       if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0)
+       err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i] || is_isapnp_selected(i))
-                       continue;
-               device = platform_device_register_simple(SND_SB16_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               cards++;
-       }
 #ifdef CONFIG_PNP
        /* PnP cards at last */
        err = pnp_register_card_driver(&sb16_pnpc_driver);
-       if (!err) {
+       if (!err)
                pnp_registered = 1;
-               cards += sb16_pnp_devices;
-       }
-#endif
-
-       if (!cards) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
-#ifdef SNDRV_SBAWE_EMU8000
-               snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n");
-#else
-               snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
 #endif
-#endif
-               snd_sb16_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_sb16_exit(void)
 {
-       snd_sb16_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnp_registered)
+               pnp_unregister_card_driver(&sb16_pnpc_driver);
+#endif
+       isa_unregister_driver(&snd_sb16_isa_driver);
 }
 
 module_init(alsa_card_sb16_init)
index 3d9d7e0107cad3828aa74b0fa4935bea38a5b26a..b279f2308aef6b25d2b55008968e7e392c070e73 100644 (file)
 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
 MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
 MODULE_LICENSE("GPL");
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("sb16/mulaw_main.csp");
+MODULE_FIRMWARE("sb16/alaw_main.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
+#endif
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
@@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
  */
 static void snd_sb_csp_free(struct snd_hwdep *hwdep)
 {
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
        int i;
+#endif
        struct snd_sb_csp *p = hwdep->private_data;
        if (p) {
                if (p->running & SNDRV_SB_CSP_ST_RUNNING)
                        snd_sb_csp_stop(p);
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
                for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
                        release_firmware(p->csp_programs[i]);
+#endif
                kfree(p);
        }
 }
@@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use
        return err;
 }
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
 #include "sb16_csp_codecs.h"
 
 static const struct firmware snd_sb_csp_static_programs[] = {
@@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
                "sb16/ima_adpcm_capture.csp",
        };
        const struct firmware *program;
-       int err;
 
        BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
        program = p->csp_programs[index];
        if (!program) {
-               err = request_firmware(&program, names[index],
-                                      p->chip->card->dev);
-               if (err >= 0)
-                       p->csp_programs[index] = program;
-               else {
-#ifdef FIRMWARE_IN_THE_KERNEL
-                       program = &snd_sb_csp_static_programs[index];
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+               program = &snd_sb_csp_static_programs[index];
 #else
+               int err = request_firmware(&program, names[index],
+                                      p->chip->card->dev);
+               if (err < 0)
                        return err;
 #endif
-               }
+               p->csp_programs[index] = program;
        }
        return snd_sb_csp_load(p, program->data, program->size, flags);
 }
index be1e83e6dea32b7132e252416c83fa2dae7872b1..a1b3786b391ea7fc56e309c263b27bcf2575622f 100644 (file)
@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 struct snd_sb8 {
        struct resource *fm_res;        /* used to block FM i/o region for legacy cards */
        struct snd_sb *chip;
@@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card)
        release_and_free_resource(acard->fm_res);
 }
 
-static int __devinit snd_sb8_probe(struct platform_device *pdev)
+static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
+{
+       if (!enable[dev])
+               return 0;
+       if (irq[dev] == SNDRV_AUTO_IRQ) {
+               snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+               return 0;
+       }
+       if (dma8[dev] == SNDRV_AUTO_DMA) {
+               snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id);
+               return 0;
+       }
+       return 1;
+}
+
+static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
 {
-       int dev = pdev->id;
        struct snd_sb *chip;
        struct snd_card *card;
        struct snd_sb8 *acard;
@@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
                chip->port,
                irq[dev], dma8[dev]);
 
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
 
        if ((err = snd_card_register(card)) < 0)
                goto _err;
 
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 
  _err:
@@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
        return err;
 }
 
-static int __devexit snd_sb8_remove(struct platform_device *pdev)
+static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(pdev));
-       platform_set_drvdata(pdev, NULL);
+       snd_card_free(dev_get_drvdata(pdev));
+       dev_set_drvdata(pdev, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb8_suspend(struct device *dev, unsigned int n,
+                          pm_message_t state)
 {
-       struct snd_card *card = platform_get_drvdata(dev);
+       struct snd_card *card = dev_get_drvdata(dev);
        struct snd_sb8 *acard = card->private_data;
        struct snd_sb *chip = acard->chip;
 
@@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
        return 0;
 }
 
-static int snd_sb8_resume(struct platform_device *dev)
+static int snd_sb8_resume(struct device *dev, unsigned int n)
 {
-       struct snd_card *card = platform_get_drvdata(dev);
+       struct snd_card *card = dev_get_drvdata(dev);
        struct snd_sb8 *acard = card->private_data;
        struct snd_sb *chip = acard->chip;
 
@@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev)
 }
 #endif
 
-#define SND_SB8_DRIVER "snd_sb8"
+#define DEV_NAME "sb8"
 
-static struct platform_driver snd_sb8_driver = {
+static struct isa_driver snd_sb8_driver = {
+       .match          = snd_sb8_match,
        .probe          = snd_sb8_probe,
        .remove         = __devexit_p(snd_sb8_remove),
 #ifdef CONFIG_PM
@@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = {
        .resume         = snd_sb8_resume,
 #endif
        .driver         = {
-               .name   = SND_SB8_DRIVER
+               .name   = DEV_NAME 
        },
 };
 
-static void __init_or_module snd_sb8_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_sb8_driver);
-}
-
 static int __init alsa_card_sb8_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_sb8_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(SND_SB8_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n");
-#endif
-               snd_sb8_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_sb8_exit(void)
 {
-       snd_sb8_unregister_all();
+       isa_unregister_driver(&snd_sb8_driver);
 }
 
 module_init(alsa_card_sb8_init)
index 4fcd0f4e868c4c67c29403b12ede58c16aeeb00f..922519def0997f2ff21ee74fc84ecb073012411c 100644 (file)
@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
@@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
 module_param_array(dma1, int, NULL, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 #define SGALAXY_AUXC_LEFT 18
 #define SGALAXY_AUXC_RIGHT 19
 
@@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port)
        return 0;
 }
 
-static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val)
+static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
+                                              unsigned char val)
 {
        int i;
                
@@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
        return IRQ_NONE;
 }
 
-static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
+static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
 {
        static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 
                                       0x10, 0x18, 0x20, -1, -1, -1, -1};
@@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
        return 0;
 }
 
-static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
+static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
 {
 #if 0
        snd_printdd(PFX "switching to WSS mode\n");
@@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7
 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
 };
 
-static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
+static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
 {
        struct snd_card *card = chip->card;
        struct snd_ctl_elem_id id1, id2;
@@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
        return 0;
 }
 
-static int __init snd_sgalaxy_probe(struct platform_device *devptr)
+static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
 {
-       int dev = devptr->id;
-       static int possible_irqs[] = {7, 9, 10, 11, -1};
-       static int possible_dmas[] = {1, 3, 0, -1};
-       int err, xirq, xdma1;
-       struct snd_card *card;
-       struct snd_ad1848 *chip;
-
+       if (!enable[dev])
+               return 0;
        if (sbport[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify SB port\n");
-               return -EINVAL;
+               return 0;
        }
        if (wssport[dev] == SNDRV_AUTO_PORT) {
                snd_printk(KERN_ERR PFX "specify WSS port\n");
-               return -EINVAL;
+               return 0;
        }
+       return 1;
+}
+
+static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
+{
+       static int possible_irqs[] = {7, 9, 10, 11, -1};
+       static int possible_dmas[] = {1, 3, 0, -1};
+       int err, xirq, xdma1;
+       struct snd_card *card;
+       struct snd_ad1848 *chip;
+
        card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
        if (card == NULL)
                return -ENOMEM;
@@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
        sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
                wssport[dev], xirq, xdma1);
 
-       snd_card_set_dev(card, &devptr->dev);
+       snd_card_set_dev(card, devptr);
 
        if ((err = snd_card_register(card)) < 0)
                goto _err;
 
-       platform_set_drvdata(devptr, card);
+       dev_set_drvdata(devptr, card);
        return 0;
 
  _err:
@@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
        return err;
 }
 
-static int __devexit snd_sgalaxy_remove(struct platform_device *devptr)
+static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
+                              pm_message_t state)
 {
-       struct snd_card *card = platform_get_drvdata(pdev);
+       struct snd_card *card = dev_get_drvdata(pdev);
        struct snd_ad1848 *chip = card->private_data;
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
        return 0;
 }
 
-static int snd_sgalaxy_resume(struct platform_device *pdev)
+static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
 {
-       struct snd_card *card = platform_get_drvdata(pdev);
+       struct snd_card *card = dev_get_drvdata(pdev);
        struct snd_ad1848 *chip = card->private_data;
 
        chip->resume(chip);
@@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev)
 }
 #endif
 
-#define SND_SGALAXY_DRIVER     "snd_sgalaxy"
+#define DEV_NAME "sgalaxy"
 
-static struct platform_driver snd_sgalaxy_driver = {
+static struct isa_driver snd_sgalaxy_driver = {
+       .match          = snd_sgalaxy_match,
        .probe          = snd_sgalaxy_probe,
        .remove         = __devexit_p(snd_sgalaxy_remove),
 #ifdef CONFIG_PM
@@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = {
        .resume         = snd_sgalaxy_resume,
 #endif
        .driver         = {
-               .name   = SND_SGALAXY_DRIVER
+               .name   = DEV_NAME
        },
 };
 
-static void __init_or_module snd_sgalaxy_unregister_all(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(devices); ++i)
-               platform_device_unregister(devices[i]);
-       platform_driver_unregister(&snd_sgalaxy_driver);
-}
-
 static int __init alsa_card_sgalaxy_init(void)
 {
-       int i, cards, err;
-
-       err = platform_driver_register(&snd_sgalaxy_driver);
-       if (err < 0)
-               return err;
-
-       cards = 0;
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-               device = platform_device_register_simple(SND_SGALAXY_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               devices[i] = device;
-               cards++;
-       }
-       if (!cards) {
-#ifdef MODULE
-               snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n");
-#endif
-               snd_sgalaxy_unregister_all();
-               return -ENODEV;
-       }
-       return 0;
+       return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_sgalaxy_exit(void)
 {
-       snd_sgalaxy_unregister_all();
+       isa_unregister_driver(&snd_sgalaxy_driver);
 }
 
 module_init(alsa_card_sgalaxy_init)
index b1f25823c652cb8708226d1e38cac5eae86cdd61..08c14978558ce20ed9dc69ae515421f79e969ed4 100644 (file)
@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
@@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
 module_param_array(dma, int, NULL, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-  
 #ifdef CONFIG_PNP
 static int pnp_registered;
 static struct pnp_card_device_id sscape_pnpids[] = {
@@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
 }
 
 
-static int __devinit snd_sscape_probe(struct platform_device *pdev)
+static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
+{
+       /*
+        * Make sure we were given ALL of the other parameters.
+        */
+       if (port[i] == SNDRV_AUTO_PORT)
+               return 0;
+
+       if (irq[i] == SNDRV_AUTO_IRQ ||
+           mpu_irq[i] == SNDRV_AUTO_IRQ ||
+           dma[i] == SNDRV_AUTO_DMA) {
+               printk(KERN_INFO
+                      "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
+               return 0;
+       }
+
+       return 1;
+}
+
+static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
 {
-       int dev = pdev->id;
        struct snd_card *card;
        int ret;
 
@@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev)
        ret = create_sscape(dev, &card);
        if (ret < 0)
                return ret;
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
        if ((ret = snd_card_register(card)) < 0) {
                printk(KERN_ERR "sscape: Failed to register sound card\n");
                return ret;
        }
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
-static int __devexit snd_sscape_remove(struct platform_device *devptr)
+static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-#define SSCAPE_DRIVER  "snd_sscape"
+#define DEV_NAME "sscape"
 
-static struct platform_driver snd_sscape_driver = {
+static struct isa_driver snd_sscape_driver = {
+       .match          = snd_sscape_match,
        .probe          = snd_sscape_probe,
        .remove         = __devexit_p(snd_sscape_remove),
        /* FIXME: suspend/resume */
        .driver         = {
-               .name   = SSCAPE_DRIVER
+               .name   = DEV_NAME
        },
 };
 
@@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module sscape_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnp_registered)
-               pnp_unregister_card_driver(&sscape_pnpc_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_sscape_driver);
-}
-
-static int __init sscape_manual_probe(void)
-{
-       struct platform_device *device;
-       int i, ret;
-
-       ret = platform_driver_register(&snd_sscape_driver);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < SNDRV_CARDS; ++i) {
-               /*
-                * We do NOT probe for ports.
-                * If we're not given a port number for this
-                * card then we completely ignore this line
-                * of parameters.
-                */
-               if (port[i] == SNDRV_AUTO_PORT)
-                       continue;
-
-               /*
-                * Make sure we were given ALL of the other parameters.
-                */
-               if (irq[i] == SNDRV_AUTO_IRQ ||
-                   mpu_irq[i] == SNDRV_AUTO_IRQ ||
-                   dma[i] == SNDRV_AUTO_DMA) {
-                       printk(KERN_INFO
-                              "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
-                       sscape_unregister_all();
-                       return -ENXIO;
-               }
-
-               /*
-                * This cards looks OK ...
-                */
-               device = platform_device_register_simple(SSCAPE_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-       }
-       return 0;
-}
-
-static void sscape_exit(void)
-{
-       sscape_unregister_all();
-}
-
-
 static int __init sscape_init(void)
 {
        int ret;
@@ -1462,7 +1413,7 @@ static int __init sscape_init(void)
         * of allocating cards, because the operator is
         * S-P-E-L-L-I-N-G it out for us...
         */
-       ret = sscape_manual_probe();
+       ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
        if (ret < 0)
                return ret;
 #ifdef CONFIG_PNP
@@ -1472,5 +1423,14 @@ static int __init sscape_init(void)
        return 0;
 }
 
+static void __exit sscape_exit(void)
+{
+#ifdef CONFIG_PNP
+       if (pnp_registered)
+               pnp_unregister_card_driver(&sscape_pnpc_driver);
+#endif
+       isa_unregister_driver(&snd_sscape_driver);
+}
+
 module_init(sscape_init);
 module_exit(sscape_exit);
index e2fdd5fd39d023c9b855808c6a16e73140ba2842..75673f723857c3190025a4be7d9bc8087cb75458 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
@@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;         /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;          /* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;     /* Enable this card */
+#ifdef CONFIG_PNP
 static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+#endif
 static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
 static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
 static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #.");
 module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
 #ifdef CONFIG_PNP
 static int pnp_registered;
 
@@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev)
        return snd_card_register(card);
 }      
 
-static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_wavefront_isa_match(struct device *pdev,
+                                            unsigned int dev)
 {
-       int dev = pdev->id;
-       struct snd_card *card;
-       int err;
-
+       if (!enable[dev])
+               return 0;
+#ifdef CONFIG_PNP
+       if (isapnp[dev])
+               return 0;
+#endif
        if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
                snd_printk("specify CS4232 port\n");
-               return -EINVAL;
+               return 0;
        }
        if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
                snd_printk("specify ICS2115 port\n");
-               return -ENODEV;
+               return 0;
        }
+       return 1;
+}
+
+static int __devinit snd_wavefront_isa_probe(struct device *pdev,
+                                            unsigned int dev)
+{
+       struct snd_card *card;
+       int err;
 
        card = snd_wavefront_card_new(dev);
        if (! card)
                return -ENOMEM;
-       snd_card_set_dev(card, &pdev->dev);
+       snd_card_set_dev(card, pdev);
        if ((err = snd_wavefront_probe(card, dev)) < 0) {
                snd_card_free(card);
                return err;
        }
        
-       platform_set_drvdata(pdev, card);
+       dev_set_drvdata(pdev, card);
        return 0;
 }
 
-static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_wavefront_isa_remove(struct device *devptr,
+                                             unsigned int dev)
 {
-       snd_card_free(platform_get_drvdata(devptr));
-       platform_set_drvdata(devptr, NULL);
+       snd_card_free(dev_get_drvdata(devptr));
+       dev_set_drvdata(devptr, NULL);
        return 0;
 }
 
-#define WAVEFRONT_DRIVER       "snd_wavefront"
+#define DEV_NAME "wavefront"
 
-static struct platform_driver snd_wavefront_driver = {
-       .probe          = snd_wavefront_nonpnp_probe,
-       .remove         = __devexit_p(snd_wavefront_nonpnp_remove),
+static struct isa_driver snd_wavefront_driver = {
+       .match          = snd_wavefront_isa_match,
+       .probe          = snd_wavefront_isa_probe,
+       .remove         = __devexit_p(snd_wavefront_isa_remove),
        /* FIXME: suspend, resume */
        .driver         = {
-               .name   = WAVEFRONT_DRIVER
+               .name   = DEV_NAME
        },
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata wavefront_pnp_devices;
-
 static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
                                               const struct pnp_card_device_id *pid)
 {
@@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
 
        pnp_set_card_drvdata(pcard, card);
        dev++;
-       wavefront_pnp_devices++;
        return 0;
 }
 
@@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_wavefront_unregister_all(void)
-{
-       int i;
-
-#ifdef CONFIG_PNP
-       if (pnp_registered)
-               pnp_unregister_card_driver(&wavefront_pnpc_driver);
-#endif
-       for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-               platform_device_unregister(platform_devices[i]);
-       platform_driver_unregister(&snd_wavefront_driver);
-}
-
 static int __init alsa_card_wavefront_init(void)
 {
-       int i, err, cards = 0;
+       int err;
 
-       if ((err = platform_driver_register(&snd_wavefront_driver)) < 0)
+       err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
+       if (err < 0)
                return err;
-
-       for (i = 0; i < SNDRV_CARDS; i++) {
-               struct platform_device *device;
-               if (! enable[i])
-                       continue;
-#ifdef CONFIG_PNP
-               if (isapnp[i])
-                       continue;
-#endif
-               device = platform_device_register_simple(WAVEFRONT_DRIVER,
-                                                        i, NULL, 0);
-               if (IS_ERR(device))
-                       continue;
-               if (!platform_get_drvdata(device)) {
-                       platform_device_unregister(device);
-                       continue;
-               }
-               platform_devices[i] = device;
-               cards++;
-       }
-
 #ifdef CONFIG_PNP
        err = pnp_register_card_driver(&wavefront_pnpc_driver);
-       if (!err) {
+       if (!err)
                pnp_registered = 1;
-               cards += wavefront_pnp_devices;
-       }
-#endif
-
-       if (!cards) {
-#ifdef MODULE
-               printk (KERN_ERR "No WaveFront cards found or devices busy\n");
 #endif
-               snd_wavefront_unregister_all();
-               return -ENODEV;
-       }
        return 0;
 }
 
 static void __exit alsa_card_wavefront_exit(void)
 {
-       snd_wavefront_unregister_all();
+#ifdef CONFIG_PNP
+       if (pnp_registered)
+               pnp_unregister_card_driver(&wavefront_pnpc_driver);
+#endif
+       isa_unregister_driver(&snd_wavefront_driver);
 }
 
 module_init(alsa_card_wavefront_init)
index 15331ed8819449b03864dcdebd062048f4f4954f..fc95a870f69017aa17cf20f175633abb0d1af8d1 100644 (file)
@@ -35,9 +35,7 @@
 
 #define WAIT_IDLE      0xff
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
 #include "yss225.c"
 static const struct firmware yss225_registers_firmware = {
        .data = (u8 *)yss225_registers,
@@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
 {
        unsigned int i;
        int err;
-       const struct firmware *firmware;
+       const struct firmware *firmware = NULL;
 
        if (dev->fx_initialized)
                return 0;
 
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+       firmware = &yss225_registers_firmware;
+#else
        err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
                               dev->card->dev);
        if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-               firmware = &yss225_registers_firmware;
-#else
                err = -1;
                goto out;
-#endif
        }
+#endif
 
        for (i = 0; i + 1 < firmware->size; i += 2) {
                if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
@@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
        err = 0;
 
 out:
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (firmware != &yss225_registers_firmware)
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+       release_firmware(firmware);
 #endif
-               release_firmware(firmware);
        return err;
 }
+
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("yamaha/yss225_registers.bin");
+#endif
index 1bcfb3aac18dce993208d423c523b564772d4887..61e35ecc57b8586eacc939111938a2ca2ad01c4b 100644 (file)
@@ -576,7 +576,7 @@ config SND_INTEL8X0M
 config SND_KORG1212
        tristate "Korg 1212 IO"
        depends on SND
-       select FW_LOADER
+       select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
        select SND_PCM
        help
          Say Y here to include support for Korg 1212IO soundcards.
@@ -584,10 +584,19 @@ config SND_KORG1212
          To compile this driver as a module, choose M here: the module
          will be called snd-korg1212.
 
+config SND_KORG1212_FIRMWARE_IN_KERNEL
+       bool "In-kernel firmware for Korg1212 driver"
+       depends on SND_KORG1212
+       default y
+       help
+         Say Y here to include the static firmware built in the kernel
+         for the Korg1212 driver.  If you choose N here, you need to
+         install the firmware files from the alsa-firmware package.
+
 config SND_MAESTRO3
        tristate "ESS Allegro/Maestro3"
        depends on SND
-       select FW_LOADER
+       select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
        select SND_AC97_CODEC
        help
          Say Y here to include support for soundcards based on ESS Maestro 3
@@ -596,6 +605,15 @@ config SND_MAESTRO3
          To compile this driver as a module, choose M here: the module
          will be called snd-maestro3.
 
+config SND_MAESTRO3_FIRMWARE_IN_KERNEL
+       bool "In-kernel firmware for Maestro3 driver"
+       depends on SND_MAESTRO3
+       default y
+       help
+         Say Y here to include the static firmware built in the kernel
+         for the Maestro3 driver.  If you choose N here, you need to
+         install the firmware files from the alsa-firmware package.
+
 config SND_MIXART
        tristate "Digigram miXart"
        depends on SND
@@ -737,7 +755,7 @@ config SND_VX222
 config SND_YMFPCI
        tristate "Yamaha YMF724/740/744/754"
        depends on SND
-       select FW_LOADER
+       select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
        select SND_OPL3_LIB
        select SND_MPU401_UART
        select SND_AC97_CODEC
@@ -748,6 +766,15 @@ config SND_YMFPCI
          To compile this driver as a module, choose M here: the module
          will be called snd-ymfpci.
 
+config SND_YMFPCI_FIRMWARE_IN_KERNEL
+       bool "In-kernel firmware for YMFPCI driver"
+       depends on SND_YMFPCI
+       default y
+       help
+         Say Y here to include the static firmware built in the kernel
+         for the YMFPCI driver.  If you choose N here, you need to
+         install the firmware files from the alsa-firmware package.
+
 config SND_AC97_POWER_SAVE
        bool "AC97 Power-Saving Mode"
        depends on SND_AC97_CODEC && EXPERIMENTAL
index 3c3222122d8b0acda0e1a4389ee8fa452da0409d..f5d471896b95951bb21b7f5a87929fc54bfc4b42 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
+snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
 
 ifneq ($(CONFIG_PROC_FS),)
 snd-ac97-codec-objs += ac97_proc.o
index 3bfb2102fc5d24c7e851df978ebd2dd3f97f775d..bbed644bf9c52d887ea8bd261ba88421cf6f9abc 100644 (file)
@@ -35,9 +35,9 @@
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include "ac97_local.h"
 #include "ac97_id.h"
-#include "ac97_patch.h"
+
+#include "ac97_patch.c"
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
@@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
  * Controls
  */
 
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_info *uinfo)
 {
        struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
        
@@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
        return 0;
 }
 
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
        struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
        return 0;
 }
 
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
        struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
 }
 
 /* volume and switch controls */
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_info *uinfo)
 {
        int mask = (kcontrol->private_value >> 16) & 0xff;
        int shift = (kcontrol->private_value >> 8) & 0x0f;
@@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
        return 0;
 }
 
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+                             struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
        int reg = kcontrol->private_value & 0xff;
@@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
        return 0;
 }
 
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+                             struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
        int reg = kcontrol->private_value & 0xff;
@@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]),
 AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
 };
 
-const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
 AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
 AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
 };
@@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
        return change;
 }
 
-const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
        {
                .access = SNDRV_CTL_ELEM_ACCESS_READ,
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
        }
 }
 
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
 {
        unsigned short mask, val, orig, res;
 
@@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x)
        return x;
 }
 
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97)
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+                                         struct snd_ac97 * ac97)
 {
        struct snd_kcontrol_new template;
        memcpy(&template, _template, sizeof(template));
@@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix)
 }      
 
 /* remove the control with the given name and optional suffix */
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix)
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+                              const char *suffix)
 {
        struct snd_ctl_elem_id id;
        memset(&id, 0, sizeof(id));
@@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co
 }
 
 /* rename the control with the given name and optional suffix */
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix)
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+                              const char *dst, const char *suffix)
 {
        struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
        if (kctl) {
@@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst,
 }
 
 /* rename both Volume and Switch controls - don't check the return value */
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst)
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+                                   const char *dst)
 {
        snd_ac97_rename_ctl(ac97, src, dst, "Switch");
        snd_ac97_rename_ctl(ac97, src, dst, "Volume");
 }
 
 /* swap controls */
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix)
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+                            const char *s2, const char *suffix)
 {
        struct snd_kcontrol *kctl1, *kctl2;
        kctl1 = ctl_find(ac97, s1, suffix);
index a6244c720a1d8762000bdcdf86fc293b9667efed..78745c5c6df85ae4a89f82f726e241b27fcbaa55 100644 (file)
  *
  */
 
-#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
-#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
-#define AC97_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
-#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)                \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
-#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
-
-/* enum control */
-struct ac97_enum {
-       unsigned char reg;
-       unsigned char shift_l;
-       unsigned char shift_r;
-       unsigned short mask;
-       const char **texts;
-};
-
-#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
-{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
-  .mask = xmask, .texts = xtexts }
-#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
-       AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
-#define AC97_ENUM(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
-  .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
-  .private_value = (unsigned long)&xenum }
-
-/* ac97_codec.c */
-extern const struct snd_kcontrol_new snd_ac97_controls_3d[];
-extern const struct snd_kcontrol_new snd_ac97_controls_spdif[];
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97);
-void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem);
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix);
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix);
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix);
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst);
-void snd_ac97_restore_status(struct snd_ac97 *ac97);
-void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-
+void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name,
+                      int modem);
 int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
                                unsigned short mask, unsigned short value);
 
index b188a4df58cbd5cc5ea7209cf8d1ed99c1cb139c..3eac0f86266ce54e0bd3a0ff2aa26bc07038081b 100644 (file)
  *
  */
 
-#include <sound/driver.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include "ac97_patch.h"
-#include "ac97_id.h"
 #include "ac97_local.h"
+#include "ac97_patch.h"
 
 /*
  *  Chip specific initialization
@@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
        .build_post_spdif = patch_yamaha_ymf753_post_spdif
 };
 
-int patch_yamaha_ymf753(struct snd_ac97 * ac97)
+static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
 {
        /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
           This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
@@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
        .build_specific = patch_wolfson_wm9703_specific,
 };
 
-int patch_wolfson03(struct snd_ac97 * ac97)
+static int patch_wolfson03(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_wolfson_wm9703_ops;
        return 0;
@@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
        .build_specific = patch_wolfson_wm9704_specific,
 };
 
-int patch_wolfson04(struct snd_ac97 * ac97)
+static int patch_wolfson04(struct snd_ac97 * ac97)
 {
        /* WM9704M/9704Q */
        ac97->build_ops = &patch_wolfson_wm9704_ops;
@@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
        .build_specific = patch_wolfson_wm9705_specific,
 };
 
-int patch_wolfson05(struct snd_ac97 * ac97)
+static int patch_wolfson05(struct snd_ac97 * ac97)
 {
        /* WM9705, WM9710 */
        ac97->build_ops = &patch_wolfson_wm9705_ops;
@@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
        .build_specific = patch_wolfson_wm9711_specific,
 };
 
-int patch_wolfson11(struct snd_ac97 * ac97)
+static int patch_wolfson11(struct snd_ac97 * ac97)
 {
        /* WM9711, WM9712 */
        ac97->build_ops = &patch_wolfson_wm9711_ops;
@@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
 #endif
 };
 
-int patch_wolfson13(struct snd_ac97 * ac97)
+static int patch_wolfson13(struct snd_ac97 * ac97)
 {
        /* WM9713, WM9714 */
        ac97->build_ops = &patch_wolfson_wm9713_ops;
@@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97)
 /*
  * Tritech codec
  */
-int patch_tritech_tr28028(struct snd_ac97 * ac97)
+static int patch_tritech_tr28028(struct snd_ac97 * ac97)
 {
        snd_ac97_write_cache(ac97, 0x26, 0x0300);
        snd_ac97_write_cache(ac97, 0x26, 0x0000);
@@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
        .build_specific = patch_sigmatel_stac97xx_specific
 };
 
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_sigmatel_stac9700_ops;
        return 0;
@@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
        .build_specific = patch_sigmatel_stac9708_specific
 };
 
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
 {
        unsigned int codec72, codec6c;
 
@@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
        return 0;
 }
 
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_sigmatel_stac9700_ops;
        if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
@@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
        return 0;
 }
 
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
 {
        // patch for SigmaTel
        ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
        return 0;
 }
 
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
 {
        // patch for SigmaTel
        ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
        .build_specific = patch_sigmatel_stac9758_specific
 };
 
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
 {
        static unsigned short regs[4] = {
                AC97_SIGMATEL_OUTSEL,
@@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = {
        .build_spdif = patch_cirrus_build_spdif
 };
 
-int patch_cirrus_spdif(struct snd_ac97 * ac97)
+static int patch_cirrus_spdif(struct snd_ac97 * ac97)
 {
        /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
           WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC?  *sigh*
@@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97)
        return 0;
 }
 
-int patch_cirrus_cs4299(struct snd_ac97 * ac97)
+static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
 {
        /* force the detection of PC Beep */
        ac97->flags |= AC97_HAS_PC_BEEP;
@@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = {
        .build_spdif = patch_conexant_build_spdif
 };
 
-int patch_conexant(struct snd_ac97 * ac97)
+static int patch_conexant(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_conexant_ops;
        ac97->flags |= AC97_CX_SPDIF;
@@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97)
        return 0;
 }
 
-int patch_cx20551(struct snd_ac97 *ac97)
+static int patch_cx20551(struct snd_ac97 *ac97)
 {
        snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
        return 0;
@@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = {
        { } /* terminator */
 };
 
-int patch_ad1819(struct snd_ac97 * ac97)
+static int patch_ad1819(struct snd_ac97 * ac97)
 {
        unsigned short scfg;
 
@@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = {
 #endif
 };
 
-int patch_ad1881(struct snd_ac97 * ac97)
+static int patch_ad1881(struct snd_ac97 * ac97)
 {
        static const char cfg_idxs[3][2] = {
                {2, 1},
@@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = {
 #endif
 };
 
-int patch_ad1885(struct snd_ac97 * ac97)
+static int patch_ad1885(struct snd_ac97 * ac97)
 {
        patch_ad1881(ac97);
        /* This is required to deal with the Intel D815EEAL2 */
@@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = {
 #endif
 };
 
-int patch_ad1886(struct snd_ac97 * ac97)
+static int patch_ad1886(struct snd_ac97 * ac97)
 {
        patch_ad1881(ac97);
        /* Presario700 workaround */
@@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
                snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
 }
 
-int patch_ad1981a(struct snd_ac97 *ac97)
+static int patch_ad1981a(struct snd_ac97 *ac97)
 {
        patch_ad1881(ac97);
        ac97->build_ops = &patch_ad1981a_build_ops;
@@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
 #endif
 };
 
-int patch_ad1981b(struct snd_ac97 *ac97)
+static int patch_ad1981b(struct snd_ac97 *ac97)
 {
        patch_ad1881(ac97);
        ac97->build_ops = &patch_ad1981b_build_ops;
@@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
        .update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1888(struct snd_ac97 * ac97)
+static int patch_ad1888(struct snd_ac97 * ac97)
 {
        unsigned short misc;
        
@@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
        .update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1980(struct snd_ac97 * ac97)
+static int patch_ad1980(struct snd_ac97 * ac97)
 {
        patch_ad1888(ac97);
        ac97->build_ops = &patch_ad1980_build_ops;
@@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
        .update_jacks = ad1985_update_jacks,
 };
 
-int patch_ad1985(struct snd_ac97 * ac97)
+static int patch_ad1985(struct snd_ac97 * ac97)
 {
        unsigned short misc;
        
@@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = {
        .update_jacks = ad1986_update_jacks,
 };
 
-int patch_ad1986(struct snd_ac97 * ac97)
+static int patch_ad1986(struct snd_ac97 * ac97)
 {
        patch_ad1881(ac97);
        ac97->build_ops = &patch_ad1986_build_ops;
@@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
        .update_jacks = alc650_update_jacks
 };
 
-int patch_alc650(struct snd_ac97 * ac97)
+static int patch_alc650(struct snd_ac97 * ac97)
 {
        unsigned short val;
 
@@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = {
        .update_jacks = alc655_update_jacks
 };
 
-int patch_alc655(struct snd_ac97 * ac97)
+static int patch_alc655(struct snd_ac97 * ac97)
 {
        unsigned int val;
 
@@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97)
                    (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
                     ac97->subsystem_device == 0x0161 || /* LG K1 Express */
                     ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
+                    ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
                     ac97->subsystem_device == 0x0061))  /* MSI S250 laptop */
                        val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
                else
@@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = {
        .update_jacks = alc850_update_jacks
 };
 
-int patch_alc850(struct snd_ac97 *ac97)
+static int patch_alc850(struct snd_ac97 *ac97)
 {
        ac97->build_ops = &patch_alc850_ops;
 
@@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = {
        .update_jacks = cm9738_update_jacks
 };
 
-int patch_cm9738(struct snd_ac97 * ac97)
+static int patch_cm9738(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_cm9738_ops;
        /* FIXME: can anyone confirm below? */
@@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = {
        .update_jacks = cm9739_update_jacks
 };
 
-int patch_cm9739(struct snd_ac97 * ac97)
+static int patch_cm9739(struct snd_ac97 * ac97)
 {
        unsigned short val;
 
@@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = {
        .update_jacks = cm9761_update_jacks
 };
 
-int patch_cm9761(struct snd_ac97 *ac97)
+static int patch_cm9761(struct snd_ac97 *ac97)
 {
        unsigned short val;
 
@@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = {
        .build_post_spdif = patch_cm9761_post_spdif     /* identical with CM9761 */
 };
 
-int patch_cm9780(struct snd_ac97 *ac97)
+static int patch_cm9780(struct snd_ac97 *ac97)
 {
        unsigned short val;
 
@@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = {
        .build_specific = patch_vt1616_specific
 };
 
-int patch_vt1616(struct snd_ac97 * ac97)
+static int patch_vt1616(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_vt1616_ops;
        return 0;
@@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97)
 /*
  * VT1617A codec
  */
+
+/*
+ * unfortunately, the vt1617a stashes the twiddlers required for
+ * nooding the i/o jacks on 2 different regs. * thameans that we cant
+ * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
+ * are own funcs.
+ *
+ * NB: this is absolutely and utterly different from the vt1618. dunno
+ * about the 1616.
+ */
+
+/* copied from ac97_surround_jack_mode_info() */
+static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_info *uinfo)
+{
+       /* ordering in this list reflects vt1617a docs for Reg 20 and
+        * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
+        * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
+        * counter-intuitive */ 
+
+       static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
+                                      "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
+                                      "LineIn Mic2", "LineIn Mic2 Mic1",
+                                      "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
+       return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
+}
+
+static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       ushort usSM51, usMS;  
+
+       struct snd_ac97 *pac97;
+       
+       pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+       /* grab our desirec bits, then mash them together in a manner
+        * consistent with Table 6 on page 17 in the 1617a docs */
+       usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
+       usMS   = snd_ac97_read(pac97, 0x20) >> 8;
+  
+       ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
+
+       return 0;
+}
+
+static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
+{
+       ushort usSM51, usMS, usReg;  
+
+       struct snd_ac97 *pac97;
+
+       pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+       usSM51 = ucontrol->value.enumerated.item[0] >> 1;
+       usMS   = ucontrol->value.enumerated.item[0] &  1;
+
+       /* push our values into the register - consider that things will be left
+        * in a funky state if the write fails */
+
+       usReg = snd_ac97_read(pac97, 0x7a);
+       snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
+       usReg = snd_ac97_read(pac97, 0x20);
+       snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS   <<  8));
+
+       return 0;
+}
+
+static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
+
+       AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
+       /*
+        * These are used to enable/disable surround sound on motherboards
+        * that have 3 bidirectional analog jacks
+        */
+       {
+               .iface         = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name          = "Smart 5.1 Select",
+               .info          = snd_ac97_vt1617a_smart51_info,
+               .get           = snd_ac97_vt1617a_smart51_get,
+               .put           = snd_ac97_vt1617a_smart51_put,
+       },
+};
+
 int patch_vt1617a(struct snd_ac97 * ac97)
 {
-       /* bring analog power consumption to normal, like WinXP driver
-        * for EPIA SP
+       int err = 0;
+
+       /* we choose to not fail out at this point, but we tell the
+          caller when we return */
+
+       err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
+                                  ARRAY_SIZE(snd_ac97_controls_vt1617a));
+
+       /* bring analog power consumption to normal by turning off the
+        * headphone amplifier, like WinXP driver for EPIA SP
         */
        snd_ac97_write_cache(ac97, 0x5c, 0x20);
        ac97->ext_id |= AC97_EI_SPDIF;  /* force the detection of spdif */
        ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
        ac97->build_ops = &patch_vt1616_ops;
-       return 0;
+
+       return err;
 }
 
 /*
@@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = {
        .update_jacks = it2646_update_jacks
 };
 
-int patch_it2646(struct snd_ac97 * ac97)
+static int patch_it2646(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_it2646_ops;
        /* full DAC volume */
@@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = {
        .build_specific = patch_si3036_specific,
 };
 
-int mpatch_si3036(struct snd_ac97 * ac97)
+static int mpatch_si3036(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_si3036_ops;
        snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
@@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = {
        { } /* terminator */
 };
 
-int patch_lm4550(struct snd_ac97 *ac97)
+static int patch_lm4550(struct snd_ac97 *ac97)
 {
        ac97->res_table = lm4550_restbl;
        return 0;
@@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = {
        .build_specific = patch_ucb1400_specific,
 };
 
-int patch_ucb1400(struct snd_ac97 * ac97)
+static int patch_ucb1400(struct snd_ac97 * ac97)
 {
        ac97->build_ops = &patch_ucb1400_ops;
        /* enable headphone driver and smart low power mode by default */
index 555d1c9a98fd724f2dc977a7ac860a4cfcf923b0..fd341ce6376204372f6a1d9ae8790846967eb57f 100644 (file)
  *
  */
 
-int patch_yamaha_ymf753(struct snd_ac97 * ac97);
-int patch_wolfson00(struct snd_ac97 * ac97);
-int patch_wolfson03(struct snd_ac97 * ac97);
-int patch_wolfson04(struct snd_ac97 * ac97);
-int patch_wolfson05(struct snd_ac97 * ac97);
-int patch_wolfson11(struct snd_ac97 * ac97);
-int patch_wolfson13(struct snd_ac97 * ac97);
-int patch_tritech_tr28028(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97);
-int patch_cirrus_cs4299(struct snd_ac97 * ac97);
-int patch_cirrus_spdif(struct snd_ac97 * ac97);
-int patch_conexant(struct snd_ac97 * ac97);
-int patch_cx20551(struct snd_ac97 * ac97);
-int patch_ad1819(struct snd_ac97 * ac97);
-int patch_ad1881(struct snd_ac97 * ac97);
-int patch_ad1885(struct snd_ac97 * ac97);
-int patch_ad1886(struct snd_ac97 * ac97);
-int patch_ad1888(struct snd_ac97 * ac97);
-int patch_ad1980(struct snd_ac97 * ac97);
-int patch_ad1981a(struct snd_ac97 * ac97);
-int patch_ad1981b(struct snd_ac97 * ac97);
-int patch_ad1985(struct snd_ac97 * ac97);
-int patch_ad1986(struct snd_ac97 * ac97);
-int patch_alc650(struct snd_ac97 * ac97);
-int patch_alc655(struct snd_ac97 * ac97);
-int patch_alc850(struct snd_ac97 * ac97);
-int patch_cm9738(struct snd_ac97 * ac97);
-int patch_cm9739(struct snd_ac97 * ac97);
-int patch_cm9761(struct snd_ac97 * ac97);
-int patch_cm9780(struct snd_ac97 * ac97);
-int patch_vt1616(struct snd_ac97 * ac97);
-int patch_vt1617a(struct snd_ac97 * ac97);
-int patch_it2646(struct snd_ac97 * ac97);
-int patch_ucb1400(struct snd_ac97 * ac97);
-int mpatch_si3036(struct snd_ac97 * ac97);
-int patch_lm4550(struct snd_ac97 * ac97);
+#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
+       ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
+        ((invert) << 24))
+#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
+       (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
+#define AC97_SINGLE(xname, reg, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_volsw,         \
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
+#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)                \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_volsw,         \
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
+#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+  .info = snd_ac97_info_volsw,         \
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
+
+/* enum control */
+struct ac97_enum {
+       unsigned char reg;
+       unsigned char shift_l;
+       unsigned char shift_r;
+       unsigned short mask;
+       const char **texts;
+};
+
+#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
+{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+  .mask = xmask, .texts = xtexts }
+#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
+       AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
+#define AC97_ENUM(xname, xenum) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_enum_double,               \
+  .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
+  .private_value = (unsigned long)&xenum }
+
+/* ac97_codec.c */
+static const struct snd_kcontrol_new snd_ac97_controls_3d[];
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+                                         struct snd_ac97 * ac97);
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+                             struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+                             struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+                              const char *suffix);
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+                              const char *dst, const char *suffix);
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+                            const char *s2, const char *suffix);
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+                                   const char *dst);
+static void snd_ac97_restore_status(struct snd_ac97 *ac97);
+static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+                                   struct snd_ctl_elem_value *ucontrol);
index 3758d07182f8013f2707971894ffe7a963c5ddf7..4281e6d0c5b66ddc4344f9375260cee0854ed325 100644 (file)
@@ -34,7 +34,6 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
-#include "ac97_patch.h"
 #include "ac97_id.h"
 #include "ac97_local.h"
 
index ba7fa22b285dd837c881f61d1856205dba58fb13..e1ed59549c5063a76ba0eb200f966ebaa0c268c8 100644 (file)
@@ -69,10 +69,10 @@ module_param(enable, bool, 0444);
  *  Debug part definitions
  */
 
-//#define ALI_DEBUG
+/* #define ALI_DEBUG */
 
 #ifdef ALI_DEBUG
-#define snd_ali_printk(format, args...) printk(format, ##args);
+#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args);
 #else
 #define snd_ali_printk(format, args...)
 #endif
@@ -105,10 +105,10 @@ module_param(enable, bool, 0444);
  *  Direct Registers
  */
 
-#define ALI_LEGACY_DMAR0        0x00  // ADR0
-#define ALI_LEGACY_DMAR4        0x04  // CNT0
-#define ALI_LEGACY_DMAR11       0x0b  // MOD 
-#define ALI_LEGACY_DMAR15       0x0f  // MMR 
+#define ALI_LEGACY_DMAR0        0x00  /* ADR0 */
+#define ALI_LEGACY_DMAR4        0x04  /* CNT0 */
+#define ALI_LEGACY_DMAR11       0x0b  /* MOD  */
+#define ALI_LEGACY_DMAR15       0x0f  /* MMR  */
 #define ALI_MPUR0              0x20
 #define ALI_MPUR1              0x21
 #define ALI_MPUR2              0x22
@@ -175,7 +175,7 @@ struct snd_ali;
 struct snd_ali_voice;
 
 struct snd_ali_channel_control {
-       // register data
+       /* register data */
        struct REGDATA {
                unsigned int start;
                unsigned int stop;
@@ -183,7 +183,7 @@ struct snd_ali_channel_control {
                unsigned int ainten;
        } data;
                
-       // register addresses
+       /* register addresses */
        struct REGS {
                unsigned int start;
                unsigned int stop;
@@ -197,19 +197,18 @@ struct snd_ali_channel_control {
 
 struct snd_ali_voice {
        unsigned int number;
-       unsigned int use: 1,
-           pcm: 1,
-           midi: 1,
-           mode: 1,
-           synth: 1;
+       unsigned int use :1,
+               pcm :1,
+               midi :1,
+               mode :1,
+               synth :1,
+               running :1;
 
        /* PCM data */
        struct snd_ali *codec;
        struct snd_pcm_substream *substream;
        struct snd_ali_voice *extra;
        
-       unsigned int running: 1;
-
        int eso;                /* final ESO value for channel */
        int count;              /* runtime->period_size */
 
@@ -231,14 +230,12 @@ struct snd_alidev {
 };
 
 
-#ifdef CONFIG_PM
 #define ALI_GLOBAL_REGS                56
 #define ALI_CHANNEL_REGS       8
 struct snd_ali_image {
-       unsigned long regs[ALI_GLOBAL_REGS];
-       unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
+       u32 regs[ALI_GLOBAL_REGS];
+       u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
 };
-#endif
 
 
 struct snd_ali {
@@ -246,8 +243,8 @@ struct snd_ali {
        unsigned long   port;
        unsigned char   revision;
 
-       unsigned int hw_initialized1;
-       unsigned int spdif_support1;
+       unsigned int hw_initialized :1;
+       unsigned int spdif_support :1;
 
        struct pci_dev  *pci;
        struct pci_dev  *pci_m1533;
@@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids);
 
 static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int);
 static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short);
-static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short);
-
-/*
- *  Debug Part
- */
-
-#ifdef ALI_DEBUG
-
-static void ali_read_regs(struct snd_ali *codec, int channel)
-{
-       int i,j;
-       unsigned int dwVal;
-
-       printk("channel %d registers map:\n", channel);
-       outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR));
-
-       printk("    ");
-       for(j=0;j<8;j++)
-               printk("%2.2x       ", j*4);
-       printk("\n");
-
-       for (i=0; i<=0xf8/4;i++) {
-               if(i%8 == 0)
-                       printk("%2.2x  ", (i*4/0x10)*0x10);
-               dwVal = inl(ALI_REG(codec,i*4));
-               printk("%8.8x ", dwVal);
-               if ((i+1)%8 == 0)
-                       printk("\n");
-       }
-       printk("\n");
-}
-static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
-{
-       unsigned int dwVal;
-       struct pci_dev *pci_dev;
-       int i,j;
-
-       pci_dev = pci_get_device(vendor, deviceid, NULL);
-       if (pci_dev == NULL)
-               return ;
-
-       printk("\nM%x PCI CFG\n", deviceid);
-       printk("    ");
-       for(j=0;j<8;j++)
-               printk("%d        ",j);
-       printk("\n");
-
-       for(i=0;i<8;i++) {
-               printk("%d   ",i);
-               for(j=0;j<8;j++)
-               {
-                       pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal);
-                       printk("%8.8x ", dwVal);
-               }
-               printk("\n");
-       }
-       pci_dev_put(pci_dev);
- }
-static void ali_read_ac97regs(struct snd_ali *codec, int secondary)
-{
-       unsigned short i,j;
-       unsigned short wVal;
-
-       printk("\ncodec %d registers map:\n", secondary);
-
-       printk("    ");
-       for(j=0;j<8;j++)
-               printk("%2.2x   ",j*2);
-       printk("\n");
-
-       for (i=0; i<64;i++) {
-               if(i%8 == 0)
-                       printk("%2.2x  ", (i/8)*0x10);
-               wVal = snd_ali_codec_peek(codec, secondary, i*2);
-               printk("%4.4x ", wVal);
-               if ((i+1)%8 == 0)
-                       printk("\n");
-       }
-       printk("\n");
-}
-
-#endif
+static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short,
+                              unsigned short);
 
 /*
  *  AC97 ACCESS
  */
 
 static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec,
-                                               unsigned int port )
+                                            unsigned int port)
 {
        return (unsigned int)inl(ALI_REG(codec, port)); 
 }
 
-static inline void snd_ali_5451_poke(  struct snd_ali *codec,
-                                       unsigned int port,
-                                       unsigned int val )
+static inline void snd_ali_5451_poke(struct snd_ali *codec,
+                                    unsigned int port,
+                                    unsigned int val)
 {
        outl((unsigned int)val, ALI_REG(codec, port));
 }
 
-static int snd_ali_codec_ready(        struct snd_ali *codec,
-                               unsigned int port )
+static int snd_ali_codec_ready(struct snd_ali *codec,
+                              unsigned int port)
 {
        unsigned long end_time;
        unsigned int res;
@@ -396,7 +313,7 @@ static int snd_ali_codec_ready(     struct snd_ali *codec,
        end_time = jiffies + msecs_to_jiffies(250);
        do {
                res = snd_ali_5451_peek(codec,port);
-               if (! (res & 0x8000))
+               if (!(res & 0x8000))
                        return 0;
                schedule_timeout_uninterruptible(1);
        } while (time_after_eq(end_time, jiffies));
@@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec)
 }
 
 static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
-                                    unsigned short reg,
-                                    unsigned short val)
+                              unsigned short reg,
+                              unsigned short val)
 {
-       unsigned int dwVal = 0;
-       unsigned int port = 0;
+       unsigned int dwVal;
+       unsigned int port;
 
        if (reg >= 0x80) {
                snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
@@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
 
        dwVal  = (unsigned int) (reg & 0xff);
        dwVal |= 0x8000 | (val << 16);
-       if (secondary) dwVal |= 0x0080;
-       if (codec->revision == ALI_5451_V02) dwVal |= 0x0100;
+       if (secondary)
+               dwVal |= 0x0080;
+       if (codec->revision == ALI_5451_V02)
+               dwVal |= 0x0100;
 
-       snd_ali_5451_poke(codec,port,dwVal);
+       snd_ali_5451_poke(codec, port, dwVal);
 
        return ;
 }
 
-static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
-                                         int secondary,
-                                         unsigned short reg)
+static unsigned short snd_ali_codec_peek(struct snd_ali *codec,
+                                        int secondary,
+                                        unsigned short reg)
 {
-       unsigned int dwVal = 0;
-       unsigned int port = 0;
+       unsigned int dwVal;
+       unsigned int port;
 
        if (reg >= 0x80) {
                snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
@@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
 
        dwVal  = (unsigned int) (reg & 0xff);
        dwVal |= 0x8000;                                /* bit 15*/
-       if (secondary) dwVal |= 0x0080;
+       if (secondary)
+               dwVal |= 0x0080;
 
        snd_ali_5451_poke(codec, port, dwVal);
 
@@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
        if (snd_ali_codec_ready(codec, port) < 0)
                return ~0;
        
-       return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
+       return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16;
 }
 
 static void snd_ali_codec_write(struct snd_ac97 *ac97,
@@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
        struct snd_ali *codec = ac97->private_data;
 
        snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
-       if(reg == AC97_GPIO_STATUS) {
-               outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE,
-                       ALI_REG(codec, ALI_AC97_GPIO));
+       if (reg == AC97_GPIO_STATUS) {
+               outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE,
+                    ALI_REG(codec, ALI_AC97_GPIO));
                return;
        }
        snd_ali_codec_poke(codec, ac97->num, reg, val);
@@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
 }
 
 
-static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
+static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97,
+                                        unsigned short reg)
 {
        struct snd_ali *codec = ac97->private_data;
 
        snd_ali_printk("codec_read reg=%xh.\n", reg);
-       return (snd_ali_codec_peek(codec, ac97->num, reg));
+       return snd_ali_codec_peek(codec, ac97->num, reg);
 }
 
 /*
@@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r
 
 static int snd_ali_reset_5451(struct snd_ali *codec)
 {
-       struct pci_dev *pci_dev = NULL;
+       struct pci_dev *pci_dev;
        unsigned short wCount, wReg;
        unsigned int   dwVal;
        
-       if ((pci_dev = codec->pci_m1533) != NULL) {
+       pci_dev = codec->pci_m1533;
+       if (pci_dev) {
                pci_read_config_dword(pci_dev, 0x7c, &dwVal);
                pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
                udelay(5000);
@@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
        wCount = 200;
        while(wCount--) {
                wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
-               if((wReg & 0x000f) == 0x000f)
+               if ((wReg & 0x000f) == 0x000f)
                        return 0;
                udelay(5000);
        }
@@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
 
 static int snd_ali_reset_codec(struct snd_ali *codec)
 {
-       struct pci_dev *pci_dev = NULL;
-       unsigned char bVal = 0;
+       struct pci_dev *pci_dev;
+       unsigned char bVal;
        unsigned int   dwVal;
        unsigned short wCount, wReg;
 
@@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
        udelay(15000);
 
        wCount = 200;
-       while(wCount--) {
+       while (wCount--) {
                wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
-               if((wReg & 0x000f) == 0x000f)
+               if ((wReg & 0x000f) == 0x000f)
                        return 0;
                udelay(5000);
        }
@@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
  *  ALI 5451 Controller
  */
 
-static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_enable_special_channel(struct snd_ali *codec,
+                                          unsigned int channel)
 {
-       unsigned long dwVal = 0;
+       unsigned long dwVal;
 
-       dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+       dwVal  = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
        dwVal |= 1 << (channel & 0x0000001f);
-       outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+       outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_special_channel(struct snd_ali *codec,
+                                           unsigned int channel)
 {
-       unsigned long dwVal = 0;
+       unsigned long dwVal;
 
-       dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+       dwVal  = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
        dwVal &= ~(1 << (channel & 0x0000001f));
-       outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+       outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_enable_address_interrupt(struct snd_ali *codec)
 {
        unsigned int gc;
 
@@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
        outl( gc, ALI_REG(codec, ALI_GC_CIR));
 }
 
-static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
 {
        unsigned int gc;
 
@@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
        outl(gc, ALI_REG(codec, ALI_GC_CIR));
 }
 
-#if 0 // not used
-static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_enable_voice_irq(struct snd_ali *codec,
+                                    unsigned int channel)
 {
        unsigned int mask;
        struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel
        snd_ali_printk("enable_voice_irq channel=%d\n",channel);
        
        mask = 1 << (channel & 0x1f);
-       pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
+       pchregs->data.ainten  = inl(ALI_REG(codec, pchregs->regs.ainten));
        pchregs->data.ainten |= mask;
-       outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+       outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
 }
 #endif
 
-static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_voice_irq(struct snd_ali *codec,
+                                     unsigned int channel)
 {
        unsigned int mask;
        struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe
        snd_ali_printk("disable_voice_irq channel=%d\n",channel);
 
        mask = 1 << (channel & 0x1f);
-       pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
+       pchregs->data.ainten  = inl(ALI_REG(codec, pchregs->regs.ainten));
        pchregs->data.ainten &= ~mask;
-       outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+       outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
 }
 
 static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
@@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
        unsigned int idx =  channel & 0x1f;
 
        if (codec->synth.chcnt >= ALI_CHANNELS){
-               snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
+               snd_printk(KERN_ERR
+                          "ali_alloc_pcm_channel: no free channels.\n");
                return -1;
        }
 
@@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec)
 
        snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
 
-       // recording
+       /* recording */
        if (rec) {
                if (codec->spdif_support &&
-                   (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT))
+                   (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+                    ALI_SPDIF_IN_SUPPORT))
                        idx = ALI_SPDIF_IN_CHANNEL;
                else
                        idx = ALI_PCM_IN_CHANNEL;
 
-               if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+               result = snd_ali_alloc_pcm_channel(codec, idx);
+               if (result >= 0)
                        return result;
-               } else {
-                       snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
+               else {
+                       snd_printk(KERN_ERR "ali_find_free_channel: "
+                                  "record channel is busy now.\n");
                        return -1;
                }
        }
 
-       //playback...
+       /* playback... */
        if (codec->spdif_support &&
-           (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) {
+           (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+            ALI_SPDIF_OUT_CH_ENABLE)) {
                idx = ALI_SPDIF_OUT_CHANNEL;
-               if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+               result = snd_ali_alloc_pcm_channel(codec, idx);
+               if (result >= 0)
                        return result;
-               } else {
-                       snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
-               }
+               else
+                       snd_printk(KERN_ERR "ali_find_free_channel: "
+                                  "S/PDIF out channel is in busy now.\n");
        }
 
        for (idx = 0; idx < ALI_CHANNELS; idx++) {
-               if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
+               result = snd_ali_alloc_pcm_channel(codec, idx);
+               if (result >= 0)
                        return result;
        }
        snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
@@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
                return;
 
        if (!(codec->synth.chmap & (1 << idx))) {
-               snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
+               snd_printk(KERN_ERR "ali_free_channel_pcm: "
+                          "channel %d is not in use.\n", channel);
                return;
        } else {
                codec->synth.chmap &= ~(1 << idx);
@@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
        }
 }
 
-#if 0 // not used
-static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel)
 {
        unsigned int mask = 1 << (channel & 0x1f);
        
@@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
 }
 #endif
 
-static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel)
+static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
 {
        unsigned int mask = 1 << (channel & 0x1f);
 
@@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval)
        currenttimer = inl(ALI_REG(codec, ALI_STIMER));
 
        while (currenttimer < begintimer + interval) {
-               if(snd_ali_stimer_ready(codec) < 0)
+               if (snd_ali_stimer_ready(codec) < 0)
                        break;
                currenttimer = inl(ALI_REG(codec,  ALI_STIMER));
+               cpu_relax();
        }
 }
 
 static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
 {
-       u16 wval  = 0;
+       u16 wval;
        u16 count = 0;
-       u8  bval = 0, R1 = 0, R2 = 0;
+       u8  bval, R1 = 0, R2;
 
-       bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+       bval  = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
        bval |= 0x1F;
-       outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+       outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1));
 
-       while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) {
+       while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) {
                count ++;
                snd_ali_delay(codec, 6);
-               bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+               bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
                R1 = bval & 0x1F;
        }
 
@@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
                snd_ali_delay(codec, 6);
                bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
                R2 = bval & 0x1F;
-               if (R2 != R1) R1 = R2; else break;
+               if (R2 != R1)
+                       R1 = R2;
+               else
+                       break;
        }
 
        if (count > 50000) {
@@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
        }
 
        if (R2 >= 0x0b && R2 <= 0x0e) {
-               wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
-               wval &= 0xE0F0;
-               wval |= (u16)0x09 << 8 | (u16)0x05;
-               outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+               wval  = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+               wval &= 0xe0f0;
+               wval |= (0x09 << 8) | 0x05;
+               outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
 
-               bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
-               outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3));
+               bval  = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0;
+               outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3));
        } else if (R2 == 0x12) {
-               wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
-               wval &= 0xE0F0;
-               wval |= (u16)0x0E << 8 | (u16)0x08;
-               outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+               wval  = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+               wval &= 0xe0f0;
+               wval |= (0x0e << 8) | 0x08;
+               outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
 
-               bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
-               outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3));
+               bval  = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0;
+               outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3));
        }
 }
 
 static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec)
 {
-       u32     dwRate = 0;
-       u8      bval = 0;
+       u32     dwRate;
+       u8      bval;
 
-       bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
-       bval &= 0x7F;
+       bval  = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
+       bval &= 0x7f;
        bval |= 0x40;
-       outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL));
+       outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL));
 
        snd_ali_detect_spdif_rate(codec);
 
-       bval  = inb(ALI_REG(codec,ALI_SPDIF_CS + 3));
-       bval &= 0x0F;
+       bval  = inb(ALI_REG(codec, ALI_SPDIF_CS + 3));
+       bval &= 0x0f;
 
-       if (bval == 0) dwRate = 44100;
-       if (bval == 1) dwRate = 48000;
-       if (bval == 2) dwRate = 32000;
+       switch (bval) {
+       case 0: dwRate = 44100; break;
+       case 1: dwRate = 48000; break;
+       case 2: dwRate = 32000; break;
+       default: dwRate = 0; break;
+       }
 
        return dwRate;
 }
@@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec)
 static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate)
 {
        unsigned char  bVal;
-       unsigned int  dwRate = 0;
+       unsigned int  dwRate;
        
-       if (rate == 32000) dwRate = 0x300;
-       if (rate == 44100) dwRate = 0;
-       if (rate == 48000) dwRate = 0x200;
+       switch (rate) {
+       case 32000: dwRate = 0x300; break;
+       case 48000: dwRate = 0x200; break;
+       default: dwRate = 0; break;
+       }
        
        bVal  = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
        bVal &= (unsigned char)(~(1<<6));
        
-       bVal |= 0x80;           //select right
+       bVal |= 0x80;           /* select right */
        outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
        outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
        
-       bVal &= (~0x80);        //select left
+       bVal &= ~0x80;  /* select left */
        outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
        outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
 }
@@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
 {
        unsigned short wVal;
        unsigned char bVal;
-
-        struct pci_dev *pci_dev = NULL;
+        struct pci_dev *pci_dev;
 
         pci_dev = codec->pci_m1533;
         if (pci_dev == NULL)
@@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
        bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
        outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
    
-       {
-               wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
-               wVal |= ALI_SPDIF_OUT_SEL_PCM;
-               outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-               snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
-       }
+       wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
+       wVal |= ALI_SPDIF_OUT_SEL_PCM;
+       outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
+       snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
 }
 
 static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
 {
-       unsigned short wVal = 0;
+       unsigned short wVal;
 
        wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
        wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
@@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
                wVal &= (~0x0002);
        outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
 */
-       snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
+       snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
 }
 
 static void snd_ali_disable_spdif_chnout(struct snd_ali *codec)
 {
-       unsigned short wVal = 0;
+       unsigned short wVal;
+
        wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
        wVal |= ALI_SPDIF_OUT_SEL_PCM;
        outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
@@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec)
        snd_ali_disable_spdif_chnout(codec);
 }
 
-static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
+static void snd_ali_update_ptr(struct snd_ali *codec, int channel)
 {
-       struct snd_ali_voice *pvoice = NULL;
+       struct snd_ali_voice *pvoice;
        struct snd_pcm_runtime *runtime;
-       struct snd_ali_channel_control *pchregs = NULL;
+       struct snd_ali_channel_control *pchregs;
        unsigned int old, mask;
 #ifdef ALI_DEBUG
        unsigned int temp, cspf;
@@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
 
        pchregs = &(codec->chregs);
 
-       // check if interrupt occurred for channel
+       /* check if interrupt occurred for channel */
        old  = pchregs->data.aint;
-       mask = ((unsigned int) 1L) << (channel & 0x1f);
+       mask = 1U << (channel & 0x1f);
 
        if (!(old & mask))
                return;
@@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
                cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
 #endif
                if (pvoice->running) {
-                       snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf);
+                       snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",
+                                      (u16)temp, cspf);
                        spin_unlock(&codec->reg_lock);
                        snd_pcm_period_elapsed(pvoice->substream);
                        spin_lock(&codec->reg_lock);
@@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
        pchregs->data.aint = old & (~mask);
 }
 
-static void snd_ali_interrupt(struct snd_ali * codec)
+static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
 {
+       struct snd_ali  *codec = dev_id;
        int channel;
        unsigned int audio_int;
-       struct snd_ali_channel_control *pchregs = NULL;
-       pchregs = &(codec->chregs);
+       struct snd_ali_channel_control *pchregs;
+
+       if (codec == NULL || !codec->hw_initialized)
+               return IRQ_NONE;
 
        audio_int = inl(ALI_REG(codec, ALI_MISCINT));
+       if (!audio_int)
+               return IRQ_NONE;
+
+       pchregs = &(codec->chregs);
        if (audio_int & ADDRESS_IRQ) {
-               // get interrupt status for all channels
-               pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint));
-               for (channel = 0; channel < ALI_CHANNELS; channel++) {
+               /* get interrupt status for all channels */
+               pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint));
+               for (channel = 0; channel < ALI_CHANNELS; channel++)
                        snd_ali_update_ptr(codec, channel);
-               }
        }
        outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
-               ALI_REG(codec,ALI_MISCINT));
-}
-
-
-static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
-{
-       struct snd_ali  *codec = dev_id;
+               ALI_REG(codec, ALI_MISCINT));
 
-       if (codec == NULL)
-               return IRQ_NONE;
-       snd_ali_interrupt(codec);
        return IRQ_HANDLED;
 }
 
 
-static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel)
+static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
+                                                int type, int rec, int channel)
 {
-       struct snd_ali_voice *pvoice = NULL;
+       struct snd_ali_voice *pvoice;
        int idx;
 
-       snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
+       snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec);
 
        spin_lock_irq(&codec->voice_alloc);
        if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
                idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
                        snd_ali_find_free_channel(codec,rec);
-               if(idx < 0) {
+               if (idx < 0) {
                        snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
                        spin_unlock_irq(&codec->voice_alloc);
                        return NULL;
@@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ
 }
 
 
-static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice)
+static void snd_ali_free_voice(struct snd_ali * codec,
+                              struct snd_ali_voice *pvoice)
 {
        void (*private_free)(void *);
        void *private_data;
@@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
        private_data = pvoice->private_data;
        pvoice->private_free = NULL;
        pvoice->private_data = NULL;
-       if (pvoice->pcm) {
+       if (pvoice->pcm)
                snd_ali_free_channel_pcm(codec, pvoice->number);
-       }
        pvoice->use = pvoice->pcm = pvoice->synth = 0;
        pvoice->substream = NULL;
        spin_unlock_irq(&codec->voice_alloc);
@@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
 }
 
 
-static void snd_ali_clear_voices(struct snd_ali * codec,
-                         unsigned int v_min,
-                         unsigned int v_max)
+static void snd_ali_clear_voices(struct snd_ali *codec,
+                                unsigned int v_min,
+                                unsigned int v_max)
 {
        unsigned int i;
 
@@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec,
        }
 }
 
-static void snd_ali_write_voice_regs(struct snd_ali * codec,
+static void snd_ali_write_voice_regs(struct snd_ali *codec,
                         unsigned int Channel,
                         unsigned int LBA,
                         unsigned int CSO,
@@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
 {
        unsigned int ctlcmds[4];
        
-       outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR));
+       outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR));
 
        ctlcmds[0] =  (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
        ctlcmds[1] =  LBA;
@@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
 
        outb(Channel, ALI_REG(codec, ALI_GC_CIR));
 
-       outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS));
-       outl(ctlcmds[1], ALI_REG(codec,ALI_LBA));
-       outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA));
-       outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC));
+       outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS));
+       outl(ctlcmds[1], ALI_REG(codec, ALI_LBA));
+       outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA));
+       outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC));
 
        outl(0x30000000, ALI_REG(codec, ALI_EBUF1));    /* Still Mode */
        outl(0x30000000, ALI_REG(codec, ALI_EBUF2));    /* Still Mode */
@@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
 {
        unsigned int delta;
 
-       if (rate < 4000)  rate = 4000;
-       if (rate > 48000) rate = 48000;
+       if (rate < 4000)
+               rate = 4000;
+       if (rate > 48000)
+               rate = 48000;
 
        if (rec) {
                if (rate == 44100)
@@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
         */
        CTRL = 0x00000001;
        if (snd_pcm_format_width(runtime->format) == 16)
-               CTRL |= 0x00000008;     // 16-bit data
+               CTRL |= 0x00000008;     /* 16-bit data */
        if (!snd_pcm_format_unsigned(runtime->format))
-               CTRL |= 0x00000002;     // signed data
+               CTRL |= 0x00000002;     /* signed data */
        if (runtime->channels > 1)
-               CTRL |= 0x00000004;     // stereo data
+               CTRL |= 0x00000004;     /* stereo data */
        return CTRL;
 }
 
@@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
  *  PCM part
  */
 
-static int snd_ali_ioctl(struct snd_pcm_substream *substream,
-                                 unsigned int cmd, void *arg)
-{
-       return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
 static int snd_ali_trigger(struct snd_pcm_substream *substream,
                               int cmd)
                                    
 {
        struct snd_ali *codec = snd_pcm_substream_chip(substream);
-       struct list_head *pos;
        struct snd_pcm_substream *s;
        unsigned int what, whati, capture_flag;
-       struct snd_ali_voice *pvoice = NULL, *evoice = NULL;
+       struct snd_ali_voice *pvoice, *evoice;
        unsigned int val;
        int do_start;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
-               do_start = 1; break;
+               do_start = 1;
+               break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               do_start = 0; break;
+               do_start = 0;
+               break;
        default:
                return -EINVAL;
        }
 
        what = whati = capture_flag = 0;
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) {
                        pvoice = s->runtime->private_data;
                        evoice = pvoice->extra;
                        what |= 1 << (pvoice->number & 0x1f);
-                       if (evoice == NULL) {
+                       if (evoice == NULL)
                                whati |= 1 << (pvoice->number & 0x1f);
-                       else {
+                       else {
                                whati |= 1 << (evoice->number & 0x1f);
                                what |= 1 << (evoice->number & 0x1f);
                        }
@@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream,
                }
        }
        spin_lock(&codec->reg_lock);
-       if (! do_start) {
+       if (!do_start)
                outl(what, ALI_REG(codec, ALI_STOP));
-       }
        val = inl(ALI_REG(codec, ALI_AINTEN));
-       if (do_start) {
+       if (do_start)
                val |= whati;
-       } else {
+       else
                val &= ~whati;
-       }
        outl(val, ALI_REG(codec, ALI_AINTEN));
-       if (do_start) {
+       if (do_start)
                outl(what, ALI_REG(codec, ALI_START));
-       }
-       snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
+       snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati);
        spin_unlock(&codec->reg_lock);
 
        return 0;
 }
 
 static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *hw_params)
+                                     struct snd_pcm_hw_params *hw_params)
 {
        struct snd_ali *codec = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_ali_voice *pvoice = runtime->private_data;
        struct snd_ali_voice *evoice = pvoice->extra;
        int err;
-       err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-       if (err < 0) return err;
+
+       err = snd_pcm_lib_malloc_pages(substream,
+                                      params_buffer_bytes(hw_params));
+       if (err < 0)
+               return err;
        
        /* voice management */
 
-       if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
-               if (evoice == NULL) {
-                       evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1);
-                       if (evoice == NULL)
+       if (params_buffer_size(hw_params) / 2 !=
+           params_period_size(hw_params)) {
+               if (!evoice) {
+                       evoice = snd_ali_alloc_voice(codec,
+                                                    SNDRV_ALI_VOICE_TYPE_PCM,
+                                                    0, -1);
+                       if (!evoice)
                                return -ENOMEM;
                        pvoice->extra = evoice;
                        evoice->substream = substream;
                }
        } else {
-               if (evoice != NULL) {
+               if (!evoice) {
                        snd_ali_free_voice(codec, evoice);
                        pvoice->extra = evoice = NULL;
                }
@@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
        struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
 
        snd_pcm_lib_free_pages(substream);
-       if (evoice != NULL) {
+       if (!evoice) {
                snd_ali_free_voice(codec, evoice);
                pvoice->extra = NULL;
        }
@@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
 }
 
 static int snd_ali_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *hw_params)
+                            struct snd_pcm_hw_params *hw_params)
 {
-       return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+       return snd_pcm_lib_malloc_pages(substream,
+                                       params_buffer_bytes(hw_params));
 }
 
 static int snd_ali_hw_free(struct snd_pcm_substream *substream)
@@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
        /* set Delta (rate) value */
        Delta = snd_ali_convert_rate(runtime->rate, 0);
 
-       if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || 
-           (pvoice->number == ALI_PCM_IN_CHANNEL))
+       if (pvoice->number == ALI_SPDIF_IN_CHANNEL || 
+           pvoice->number == ALI_PCM_IN_CHANNEL)
                snd_ali_disable_special_channel(codec, pvoice->number);
        else if (codec->spdif_support &&
-                (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
-                && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) {
+                (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+                 ALI_SPDIF_OUT_CH_ENABLE)
+                && pvoice->number == ALI_SPDIF_OUT_CHANNEL) {
                snd_ali_set_spdif_out_rate(codec, runtime->rate);
                Delta = 0x1000;
        }
@@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
        /* set target ESO for channel */
        pvoice->eso = runtime->buffer_size; 
 
-       snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count);
+       snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",
+                      pvoice->eso, pvoice->count);
 
        /* set ESO to capture first MIDLP interrupt */
        ESO = pvoice->eso -1;
@@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
        PAN = 0;
        VOL = 0;
        EC = 0;
-       snd_ali_printk("playback_prepare:\n    ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
-       snd_ali_write_voice_regs(    codec,
-                                    pvoice->number,
-                                    LBA,
-                                    0, /* cso */
-                                    ESO,
-                                    Delta,
-                                    0, /* alpha */
-                                    GVSEL,
-                                    PAN,
-                                    VOL,
-                                    CTRL,
-                                    EC);
-       if (evoice != NULL) {
+       snd_ali_printk("playback_prepare:\n");
+       snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",
+                      pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
+       snd_ali_write_voice_regs(codec,
+                                pvoice->number,
+                                LBA,
+                                0,     /* cso */
+                                ESO,
+                                Delta,
+                                0,     /* alpha */
+                                GVSEL,
+                                PAN,
+                                VOL,
+                                CTRL,
+                                EC);
+       if (!evoice) {
                evoice->count = pvoice->count;
                evoice->eso = pvoice->count << 1;
                ESO = evoice->eso - 1;
                snd_ali_write_voice_regs(codec,
-                                    evoice->number,
-                                    LBA,
-                                    0, /* cso */
-                                    ESO,
-                                    Delta,
-                                    0, /* alpha */
-                                    GVSEL,
-                                    (unsigned int)0x7f,
-                                    (unsigned int)0x3ff,
-                                    CTRL,
-                                    EC);
+                                        evoice->number,
+                                        LBA,
+                                        0,     /* cso */
+                                        ESO,
+                                        Delta,
+                                        0,     /* alpha */
+                                        GVSEL,
+                                        0x7f,
+                                        0x3ff,
+                                        CTRL,
+                                        EC);
        }
        spin_unlock_irq(&codec->reg_lock);
        return 0;
@@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
                 pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 
                0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
 
-       // Prepare capture intr channel
+       /* Prepare capture intr channel */
        if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
 
                unsigned int rate;
@@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
 
                rate = snd_ali_get_spdif_in_rate(codec);
                if (rate == 0) {
-                       snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
+                       snd_printk(KERN_WARNING "ali_capture_preapre: "
+                                  "spdif rate detect err!\n");
                        rate = 48000;
                }
                spin_lock_irq(&codec->reg_lock);
@@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
                }
 
                if (rate != 48000)
-                       Delta = ((rate << 12)/runtime->rate)&0x00ffff;
+                       Delta = ((rate << 12) / runtime->rate) & 0x00ffff;
        }
 
-       // set target ESO for channel 
+       /* set target ESO for channel  */
        pvoice->eso = runtime->buffer_size; 
 
-       // set interrupt count size 
+       /* set interrupt count size  */
        pvoice->count = runtime->period_size;
 
-       // set Loop Back Address 
+       /* set Loop Back Address  */
        LBA = runtime->dma_addr;
 
-       // set ESO to capture first MIDLP interrupt 
+       /* set ESO to capture first MIDLP interrupt  */
        ESO = pvoice->eso - 1;
        CTRL = snd_ali_control_mode(substream);
        GVSEL = 0;
@@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
                                     CTRL,
                                     EC);
 
-
        spin_unlock_irq(&codec->reg_lock);
 
        return 0;
 }
 
 
-static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t
+snd_ali_playback_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_ali *codec = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
 
 static struct snd_pcm_hardware snd_ali_playback =
 {
-       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                SNDRV_PCM_INFO_MMAP_VALID |
-                                SNDRV_PCM_INFO_RESUME |
-                                SNDRV_PCM_INFO_SYNC_START),
-       .formats =              (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
-                                SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
-       .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+       .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+                        SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                        SNDRV_PCM_INFO_MMAP_VALID |
+                        SNDRV_PCM_INFO_RESUME |
+                        SNDRV_PCM_INFO_SYNC_START),
+       .formats =      (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+                        SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+       .rates =        SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
        .rate_min =             4000,
        .rate_max =             48000,
        .channels_min =         1,
@@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback =
 
 static struct snd_pcm_hardware snd_ali_capture =
 {
-       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                SNDRV_PCM_INFO_MMAP_VALID |
-                                SNDRV_PCM_INFO_RESUME |
-                                SNDRV_PCM_INFO_SYNC_START),
-       .formats =              (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
-                                SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
-       .rates =                SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+       .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+                        SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                        SNDRV_PCM_INFO_MMAP_VALID |
+                        SNDRV_PCM_INFO_RESUME |
+                        SNDRV_PCM_INFO_SYNC_START),
+       .formats =      (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+                        SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+       .rates =        SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
        .rate_min =             4000,
        .rate_max =             48000,
        .channels_min =         1,
@@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
        }
 }
 
-static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel,
-               struct snd_pcm_hardware *phw)
+static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
+                       int channel, struct snd_pcm_hardware *phw)
 {
        struct snd_ali *codec = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_ali_voice *pvoice;
 
-       pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
-       if (pvoice == NULL)
+       pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec,
+                                    channel);
+       if (!pvoice)
                return -EAGAIN;
 
        pvoice->substream = substream;
@@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe
 
        runtime->hw = *phw;
        snd_pcm_set_sync(substream);
-       snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
+       snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+                                    0, 64*1024);
        return 0;
 }
 
@@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream)
 static struct snd_pcm_ops snd_ali_playback_ops = {
        .open =         snd_ali_playback_open,
        .close =        snd_ali_playback_close,
-       .ioctl =        snd_ali_ioctl,
+       .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_ali_playback_hw_params,
        .hw_free =      snd_ali_playback_hw_free,
        .prepare =      snd_ali_playback_prepare,
@@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = {
 static struct snd_pcm_ops snd_ali_capture_ops = {
        .open =         snd_ali_capture_open,
        .close =        snd_ali_close,
-       .ioctl =        snd_ali_ioctl,
+       .ioctl =        snd_pcm_lib_ioctl,
        .hw_params =    snd_ali_hw_params,
        .hw_free =      snd_ali_hw_free,
        .prepare =      snd_ali_prepare,
@@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_ali *chip = snd_pcm_substream_chip(substream);
        unsigned int modem_num = chip->num_of_codecs - 1;
-       snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
+       snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE,
+                      params_rate(hw_params));
        snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
        return snd_ali_hw_params(substream, hw_params);
 }
 
 static struct snd_pcm_hardware snd_ali_modem =
 {
-       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                SNDRV_PCM_INFO_MMAP_VALID |
-                                SNDRV_PCM_INFO_RESUME |
-                                SNDRV_PCM_INFO_SYNC_START),
-       .formats =              SNDRV_PCM_FMTBIT_S16_LE,
-       .rates =                SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000,
+       .info =         (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+                        SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                        SNDRV_PCM_INFO_MMAP_VALID |
+                        SNDRV_PCM_INFO_RESUME |
+                        SNDRV_PCM_INFO_SYNC_START),
+       .formats =      SNDRV_PCM_FMTBIT_S16_LE,
+       .rates =        (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 |
+                        SNDRV_PCM_RATE_16000),
        .rate_min =             8000,
        .rate_max =             16000,
        .channels_min =         1,
@@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem =
        .fifo_size =            0,
 };
 
-static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel)
+static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec,
+                             int channel)
 {
-       static unsigned int rates [] = {8000,9600,12000,16000};
+       static unsigned int rates[] = {8000, 9600, 12000, 16000};
        static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
                .count = ARRAY_SIZE(rates),
                .list = rates,
                .mask = 0,
        };
        int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
+
        if (err)
                return err;
        return snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm)
 }
 
 
-static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc)
+static int __devinit snd_ali_pcm(struct snd_ali * codec, int device,
+                                struct ali_pcm_description *desc)
 {
        struct snd_pcm *pcm;
        int err;
@@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
        pcm->private_data = codec;
        pcm->private_free = snd_ali_pcm_free;
        if (desc->playback_ops)
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                               desc->playback_ops);
        if (desc->capture_ops)
-               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops);
+               snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                               desc->capture_ops);
 
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                             snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
+                                             snd_dma_pci_data(codec->pci),
+                                             64*1024, 128*1024);
 
        pcm->info_flags = 0;
        pcm->dev_class = desc->class;
@@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
 }
 
 static struct ali_pcm_description ali_pcms[] = {
-       { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
-       { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
+       { .name = "ALI 5451",
+         .playback_num = ALI_CHANNELS,
+         .capture_num = 1,
+         .playback_ops = &snd_ali_playback_ops,
+         .capture_ops = &snd_ali_capture_ops
+       },
+       { .name = "ALI 5451 modem",
+         .playback_num = 1,
+         .capture_num = 1,
+         .playback_ops = &snd_ali_modem_playback_ops,
+         .capture_ops = &snd_ali_modem_capture_ops,
+         .class = SNDRV_PCM_CLASS_MODEM
+       }
 };
 
 static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
 {
        int i, err;
-       for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
-               if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0)
+       for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) {
+               err = snd_ali_pcm(codec, i, &ali_pcms[i]);
+               if (err < 0)
                        return err;
+       }
        return 0;
 }
 
@@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
 .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
 .put = snd_ali5451_spdif_put, .private_value = value}
 
-static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
         return 0;
 }
 
-static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ali *codec = kcontrol->private_data;
        unsigned int enable;
@@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        enable = ucontrol->value.integer.value[0] ? 1 : 0;
 
        spin_lock_irq(&codec->reg_lock);
-       switch(kcontrol->private_value) {
+       switch (kcontrol->private_value) {
        case 0:
                enable = (codec->spdif_mask & 0x02) ? 1 : 0;
                break;
        case 1:
-               enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;
+               enable = ((codec->spdif_mask & 0x02) &&
+                         (codec->spdif_mask & 0x04)) ? 1 : 0;
                break;
        case 2:
                enable = (codec->spdif_mask & 0x01) ? 1 : 0;
@@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        return 0;
 }
 
-static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ali *codec = kcontrol->private_data;
        unsigned int change = 0, enable = 0;
@@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
        ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
 };
 
-static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
-       struct snd_ali *codec = bus->private_data;
-       codec->ac97_bus = NULL;
-}
-
-static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97)
-{
-       struct snd_ali *codec = ac97->private_data;
-       codec->ac97[ac97->num] = NULL;
-}
-
 static int __devinit snd_ali_mixer(struct snd_ali * codec)
 {
        struct snd_ac97_template ac97;
@@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
                .read = snd_ali_codec_read,
        };
 
-       if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0)
+       err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus);
+       if (err < 0)
                return err;
-       codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus;
 
        memset(&ac97, 0, sizeof(ac97));
        ac97.private_data = codec;
-       ac97.private_free = snd_ali_mixer_free_ac97;
 
-       for ( i = 0 ; i < codec->num_of_codecs ; i++) {
+       for (i = 0; i < codec->num_of_codecs; i++) {
                ac97.num = i;
-               if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
-                       snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
-                       if(i == 0)
+               err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]);
+               if (err < 0) {
+                       snd_printk(KERN_ERR
+                                  "ali mixer %d creating error.\n", i);
+                       if (i == 0)
                                return err;
                        codec->num_of_codecs = 1;
                        break;
@@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
        }
 
        if (codec->spdif_support) {
-               for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
-                       err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
-                       if (err < 0) return err;
+               for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
+                       err = snd_ctl_add(codec->card,
+                                         snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
+                       if (err < 0)
+                               return err;
                }
        }
        return 0;
@@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
        int i, j;
 
        im = chip->image;
-       if (! im)
+       if (!im)
                return 0;
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-       for(i = 0 ; i < chip->num_of_codecs ; i++) {
+       for (i = 0; i < chip->num_of_codecs; i++) {
                snd_pcm_suspend_all(chip->pcm[i]);
                snd_ac97_suspend(chip->ac97[i]);
        }
@@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
        spin_lock_irq(&chip->reg_lock);
        
        im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
-       // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));
+       /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */
        im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
        
-       // disable all IRQ bits
+       /* disable all IRQ bits */
        outl(0, ALI_REG(chip, ALI_MISCINT));
        
        for (i = 0; i < ALI_GLOBAL_REGS; i++) { 
@@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
                        im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
        }
 
-       // stop all HW channel
+       /* stop all HW channel */
        outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
        spin_unlock_irq(&chip->reg_lock);
@@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci)
        int i, j;
 
        im = chip->image;
-       if (! im)
+       if (!im)
                return 0;
 
        pci_set_power_state(pci, PCI_D0);
@@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci)
        }
        
        for (i = 0; i < ALI_GLOBAL_REGS; i++) { 
-               if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))
+               if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
+                   (i*4 == ALI_START))
                        continue;
                outl(im->regs[i], ALI_REG(chip, i*4));
        }
        
-       // start HW channel
+       /* start HW channel */
        outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
-       // restore IRQ enable bits
+       /* restore IRQ enable bits */
        outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
        
        spin_unlock_irq(&chip->reg_lock);
 
-       for(i = 0 ; i < chip->num_of_codecs ; i++)
+       for (i = 0 ; i < chip->num_of_codecs; i++)
                snd_ac97_resume(chip->ac97[i]);
        
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 {
        unsigned int legacy;
        unsigned char temp;
-       struct pci_dev *pci_dev = NULL;
+       struct pci_dev *pci_dev;
 
        snd_ali_printk("chip initializing ... \n");
 
@@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec)
        outb(0x10,       ALI_REG(codec, ALI_MPUR2));
 
        codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
-       codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);
+       codec->ac97_ext_status = snd_ali_codec_peek(codec, 0,
+                                                   AC97_EXTENDED_STATUS);
        if (codec->spdif_support) {
                snd_ali_enable_spdif_out(codec);
                codec->spdif_mask = 0x00000002;
@@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec)
        if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
                codec->num_of_codecs++;
                outl(inl(ALI_REG(codec, ALI_SCTRL)) |
-                       (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN),
-                       ALI_REG(codec, ALI_SCTRL));
+                    (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 |
+                     ALI_SCTRL_LINE_OUT_EN),
+                    ALI_REG(codec, ALI_SCTRL));
        }
 
        snd_ali_printk("chip initialize succeed.\n");
@@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 }
 
 /* proc for register dump */
-static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
+static void snd_ali_proc_read(struct snd_info_entry *entry,
+                             struct snd_info_buffer *buf)
 {
        struct snd_ali *codec = entry->private_data;
        int i;
-       for(i = 0 ; i < 256 ; i+= 4)
+       for (i = 0; i < 256 ; i+= 4)
                snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
 }
 
 static void __devinit snd_ali_proc_init(struct snd_ali *codec)
 {
        struct snd_info_entry *entry;
-       if(!snd_card_proc_new(codec->card, "ali5451", &entry))
+       if (!snd_card_proc_new(codec->card, "ali5451", &entry))
                snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
 }
 
@@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
        int err;
 
        snd_ali_printk("resouces allocation ...\n");
-       if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0)
+       err = pci_request_regions(codec->pci, "ALI 5451");
+       if (err < 0)
                return err;
        codec->port = pci_resource_start(codec->pci, 0);
 
@@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
        snd_ali_printk("resouces allocated.\n");
        return 0;
 }
-static int snd_ali_dev_free(struct snd_device *device) 
+static int snd_ali_dev_free(struct snd_device *device)
 {
-       struct snd_ali *codec=device->device_data;
+       struct snd_ali *codec = device->device_data;
        snd_ali_free(codec);
        return 0;
 }
@@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card,
        snd_ali_printk("creating ...\n");
 
        /* enable PCI device */
-       if ((err = pci_enable_device(pci)) < 0)
+       err = pci_enable_device(pci);
+       if (err < 0)
                return err;
        /* check, if we can restrict PCI DMA transfers to 31 bits */
        if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 ||
            pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) {
-               snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
+               snd_printk(KERN_ERR "architecture does not support "
+                          "31bit PCI busmaster DMA\n");
                pci_disable_device(pci);
                return -ENXIO;
        }
 
-       if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) {
+       codec = kzalloc(sizeof(*codec), GFP_KERNEL);
+       if (!codec) {
                pci_disable_device(pci);
                return -ENOMEM;
        }
@@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card,
 
        /* M1533: southbridge */
        codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
-       if (! codec->pci_m1533) {
+       if (!codec->pci_m1533) {
                snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
                snd_ali_free(codec);
                return -ENODEV;
        }
        /* M7101: power management */
        codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
-       if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
+       if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) {
                snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
                snd_ali_free(codec);
                return -ENODEV;
        }
 
        snd_ali_printk("snd_device_new is called.\n");
-       if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
+       err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops);
+       if (err < 0) {
                snd_ali_free(codec);
                return err;
        }
@@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card,
        snd_card_set_dev(card, &pci->dev);
 
        /* initialise synth voices*/
-       for (i = 0; i < ALI_CHANNELS; i++ ) {
+       for (i = 0; i < ALI_CHANNELS; i++)
                codec->synth.voices[i].number = i;
-       }
 
-       if ((err = snd_ali_chip_init(codec)) < 0) {
+       err = snd_ali_chip_init(codec);
+       if (err < 0) {
                snd_printk(KERN_ERR "ali create: chip init error.\n");
                return err;
        }
 
 #ifdef CONFIG_PM
        codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
-       if (! codec->image)
+       if (!codec->image)
                snd_printk(KERN_WARNING "can't allocate apm buffer\n");
 #endif
 
@@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
        snd_ali_printk("probe ...\n");
 
        card = snd_card_new(index, id, THIS_MODULE, 0);
-       if (card == NULL)
+       if (!card)
                return -ENOMEM;
 
-       if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       err = snd_ali_create(card, pci, pcm_channels, spdif, &codec);
+       if (err < 0)
+               goto error;
        card->private_data = codec;
 
        snd_ali_printk("mixer building ...\n");
-       if ((err = snd_ali_mixer(codec)) < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       err = snd_ali_mixer(codec);
+       if (err < 0)
+               goto error;
        
        snd_ali_printk("pcm building ...\n");
-       if ((err = snd_ali_build_pcms(codec)) < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       err = snd_ali_build_pcms(codec);
+       if (err < 0)
+               goto error;
 
        snd_ali_proc_init(codec);
 
@@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
                card->shortname, codec->port, codec->irq);
 
        snd_ali_printk("register card.\n");
-       if ((err = snd_card_register(card)) < 0) {
-               snd_card_free(card);
-               return err;
-       }
+       err = snd_card_register(card);
+       if (err < 0)
+               goto error;
+
        pci_set_drvdata(pci, card);
        return 0;
+
+ error:
+       snd_card_free(card);
+       return err;
 }
 
 static void __devexit snd_ali_remove(struct pci_dev *pci)
diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h
deleted file mode 100644 (file)
index 5a4d8fc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/***************************************************************************
- *            au88x0_sb.h
- *
- *  Wed Oct 29 22:10:42 2003
- *  
- ****************************************************************************/
-
-#ifdef CHIP_AU8820
-/* AU8820 starting @ 64KiB offset */
-#define SBEMU_BASE 0x10000
-#else
-/* AU8810? and AU8830 starting @ 164KiB offset */
-#define SBEMU_BASE 0x29000
-#endif
-
-#define FM_A_STATUS                    (SBEMU_BASE + 0x00)     /* read */
-#define FM_A_ADDRESS           (SBEMU_BASE + 0x00)     /* write */
-#define FM_A_DATA                      (SBEMU_BASE + 0x04)
-#define FM_B_STATUS                    (SBEMU_BASE + 0x08)
-#define FM_B_ADDRESS           (SBEMU_BASE + 0x08)
-#define FM_B_DATA                      (SBEMU_BASE + 0x0C)
-#define SB_MIXER_ADDR          (SBEMU_BASE + 0x10)
-#define SB_MIXER_DATA          (SBEMU_BASE + 0x14)
-#define SB_RESET                       (SBEMU_BASE + 0x18)
-#define SB_RESET_ALIAS         (SBEMU_BASE + 0x1C)
-#define FM_STATUS2                     (SBEMU_BASE + 0x20)
-#define FM_ADDR2                       (SBEMU_BASE + 0x20)
-#define FM_DATA2                       (SBEMU_BASE + 0x24)
-#define SB_DSP_READ                    (SBEMU_BASE + 0x28)
-#define SB_DSP_WRITE           (SBEMU_BASE + 0x30)
-#define SB_DSP_WRITE_STATUS    (SBEMU_BASE + 0x30)     /* bit 7 */
-#define SB_DSP_READ_STATUS     (SBEMU_BASE + 0x38)     /* bit 7 */
-#define SB_LACR                                (SBEMU_BASE + 0x40)     /* ? */
-#define SB_LADCR                       (SBEMU_BASE + 0x44)     /* ? */
-#define SB_LAMR                                (SBEMU_BASE + 0x48)     /* ? */
-#define SB_LARR                                (SBEMU_BASE + 0x4C)     /* ? */
-#define SB_VERSION                     (SBEMU_BASE + 0x50)
-#define SB_CTRLSTAT                    (SBEMU_BASE + 0x54)
-#define SB_TIMERSTAT           (SBEMU_BASE + 0x58)
-#define FM_RAM                         (SBEMU_BASE + 0x100)    /* 0x40 ULONG */
index 43edd2839b5afa7e9da3e8d5368d2e118023f03d..36d3666a5b7747b74d993e1fc012d01d1a43a571 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- *  Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
+ *  Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de>
  *
  *  Framework borrowed from Bart Hartgers's als4000.c.
  *  Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -52,6 +52,9 @@
  *  - full duplex 16bit playback/record at independent sampling rate
  *  - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
  *  - game port (legacy address support)
+ *  - builtin 3D enhancement (said to be YAMAHA Ymersion)
+ *  - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
+ *    features supported)
  *  - built-in General DirectX timer having a 20 bits counter
  *    with 1us resolution (see below!)
  *  - I2S serial port for external DAC
  * 
  * BUGS
  *  - full-duplex might *still* be problematic, not fully tested recently
+ *  - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
+ *    if you set PCM output switch to "pre 3D" instead of "post 3D".
+ *    If this can't be set, then get a mixer application that Isn't Stupid (tm)
+ *    (e.g. kmix, gamix) - unfortunately several are!!
  * 
  * TODO
  *  - test MPU401 MIDI playback etc.
@@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
        return (nreg != oreg);
 }
 
-static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
        AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
        AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
        AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
@@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
        AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
        AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
        AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
-       AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
+       AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
        AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
        AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
        AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
@@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
 #endif
 };
 
-static const u16 __devinitdata snd_azf3328_init_values[][2] = {
+static u16 __devinitdata snd_azf3328_init_values[][2] = {
         { IDX_MIXER_PLAY_MASTER,       MIXER_MUTE_MASK|0x1f1f },
         { IDX_MIXER_MODEMOUT,          MIXER_MUTE_MASK|0x1f1f },
        { IDX_MIXER_BASSTREBLE,         0x0000 },
@@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
        struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 
        snd_azf3328_dbgcallenter();
-
        chip->playback_substream = NULL;
        snd_azf3328_dbgcallleave();
        return 0;
@@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
 }
 #endif
 
+#if DEBUG_MISC
 static void
 snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
 {
-#if DEBUG_MISC
        u16 tmp;
 
        snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
@@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
        for (tmp=0; tmp <= 0x01; tmp += 1)
                snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
 
-       for (tmp = 0; tmp <= 0x6E; tmp += 2)
-               snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
-#endif
+       for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
+               snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));
+
+       for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
+               snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));
 }
+#else
+static inline void
+snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
+#endif
 
 static int __devinit
 snd_azf3328_create(struct snd_card *card,
@@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 
 #ifdef MODULE
        printk(
-"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
-"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
+"azt3328: Hardware was completely undocumented, unfortunately.\n"
 "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
 "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
        1024000 / seqtimer_scaling, seqtimer_scaling);
index b4f3e3cd006bd2f5c1ec5355ef9e71005299eed5..679fa992e2bc4db09f5e8a1066e55620295f5e1b 100644 (file)
   #define IRQ_RECORDING                        0x0002
   #define IRQ_MPU401                   0x0010
   #define IRQ_TIMER                    0x0020 /* DirectX timer */
-  #define IRQ_UNKNOWN1                 0x0040 /* probably unused */
-  #define IRQ_UNKNOWN2                 0x0080 /* probably unused */
+  #define IRQ_UNKNOWN1                 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */
+  #define IRQ_UNKNOWN2                 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */
 #define IDX_IO_66H             0x66    /* writing 0xffff returns 0x0000 */
 #define IDX_IO_SOME_VALUE      0x68    /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
 #define IDX_IO_6AH             0x6A    /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
index e9b029e1cd6dd626d4fb8586695acc3813c53950..6523ba07db963eca79b03126eee27b5244f63576 100644 (file)
@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
        /* Viewcast Osprey 200 */
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+       /* ATI TV-Wonder */
+       BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
        /* Leadtek Winfast tv 2000xp delux */
        BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
        /* Voodoo TV 200 */
@@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
                   pci->device, pci->subsystem_vendor, pci->subsystem_device);
        snd_printk(KERN_DEBUG "please mail id, board name, and, "
                   "if it works, the correct digital_rate option to "
-                  "<alsa-devel@lists.sf.net>\n");
+                  "<alsa-devel@alsa-project.org>\n");
        return 32000; /* default rate */
 }
 
index ea6712b63c9f7a268eba7b72ef989d58fbda1056..48f3f17c5170283a4e18b7df9ec44f3570a58520 100644 (file)
@@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
        struct snd_ca0106_pcm *epcm;
        int channel;
        int result = 0;
-       struct list_head *pos;
         struct snd_pcm_substream *s;
        u32 basic = 0;
        u32 extended = 0;
@@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
                running=0;
                break;
        }
-        snd_pcm_group_for_each(pos, substream) {
-                s = snd_pcm_group_substream_entry(pos);
+        snd_pcm_group_for_each_entry(s, substream) {
                runtime = s->runtime;
                epcm = runtime->private_data;
                channel = epcm->channel_id;
index 2ae539b195fdd95f8de6d508a90ebbde67fc1ec0..bef1f6d1859c210917b8e09f7ccaa4fbd2df8129 100644 (file)
@@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
        snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
        snd_printk(KERN_ERR "       Try reloading the ALSA driver, if you find something\n");
         snd_printk(KERN_ERR "       broken or not working on your soundcard upon\n");
-       snd_printk(KERN_ERR "       this message please report to alsa-devel@lists.sourceforge.net\n");
+       snd_printk(KERN_ERR "       this message please report to alsa-devel@alsa-project.org\n");
 
        return -EIO;
 #endif
diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h
deleted file mode 100644 (file)
index a64c6ff..0000000
+++ /dev/null
@@ -1,1607 +0,0 @@
-/* generated from cwcemb80.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcemb80_H__
-#define __HEADER_cwcemb80_H__
-
-static struct dsp_symbol_entry cwcemb80_symbols[] = {
-  { 0x0000, "BEGINADDRESS",0x00 },
-  { 0x8000, "EXECCHILD",0x03 },
-  { 0x8001, "EXECCHILD_98",0x03 },
-  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
-  { 0x8008, "EXECSIBLING",0x03 },
-  { 0x800a, "EXECSIBLING_298",0x03 },
-  { 0x800b, "EXECSIBLING_2IND1",0x03 },
-  { 0x8010, "TIMINGMASTER",0x03 },
-  { 0x804f, "S16_CODECINPUTTASK",0x03 },
-  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
-  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
-  { 0x809a, "S16_MIX",0x03 },
-  { 0x80bb, "S16_UPSRC",0x03 },
-  { 0x813b, "MIX3_EXP",0x03 },
-  { 0x8164, "DECIMATEBYPOW2",0x03 },
-  { 0x8197, "VARIDECIMATE",0x03 },
-  { 0x81f2, "_3DINPUTTASK",0x03 },
-  { 0x820a, "_3DPRLGCINPTASK",0x03 },
-  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
-  { 0x8242, "_3DOUTPUTTASK",0x03 },
-  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
-  { 0x82c6, "WAIT4DATA",0x03 },
-  { 0x82fa, "PROLOGIC",0x03 },
-  { 0x8496, "DECORRELATOR",0x03 },
-  { 0x84a4, "STEREO2MONO",0x03 },
-  { 0x0070, "SPOSCB",0x02 },
-  { 0x0105, "TASKTREETHREAD",0x03 },
-  { 0x0136, "TASKTREEHEADERCODE",0x03 },
-  { 0x013f, "FGTASKTREEHEADERCODE",0x03 },
-  { 0x0163, "NULLALGORITHM",0x03 },
-  { 0x0167, "HFGEXECCHILD",0x03 },
-  { 0x0168, "HFGEXECCHILD_98",0x03 },
-  { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 },
-  { 0x016d, "HFGEXECSIBLING",0x03 },
-  { 0x016f, "HFGEXECSIBLING_298",0x03 },
-  { 0x0170, "HFGEXECSIBLING_2IND1",0x03 },
-  { 0x0173, "S16_CODECOUTPUTTASK",0x03 },
-  { 0x018e, "#CODE_END",0x00 },
-}; /* cwcemb80 symbols */
-
-static u32 cwcemb80_code[] = {
-/* BEGINADDRESS */
-/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
-/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
-/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
-/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
-/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
-/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
-/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
-/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
-/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
-/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
-/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
-/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
-/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
-/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
-/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
-/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
-/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
-/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002,
-/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
-/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
-/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
-/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
-/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
-/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
-/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
-/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
-/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
-/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
-/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
-/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0,
-/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b,
-/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44,
-/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917,
-/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880,
-/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000,
-/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000,
-/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1,
-/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000,
-/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500,
-/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800,
-/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80,
-/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080,
-/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540,
-/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40,
-/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240,
-/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
-/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
-/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c,
-/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
-/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
-/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
-/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
-/* 0104 */ 0x0000ba01,0x00000000,
-/* TASKTREETHREAD */
-/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
-/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
-/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
-/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa,
-/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
-/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000,
-/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
-/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008,
-/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
-/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0,
-/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
-/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009,
-/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
-/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000,
-/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000,
-/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008,
-/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000,
-/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000,
-/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
-/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000,
-/* 0135 */ 0x00000000,0x00000000,
-/* TASKTREEHEADERCODE */
-/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b,
-/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-/* 013E */ 0x00042731,0x00001003,
-/* FGTASKTREEHEADERCODE */
-/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a,
-/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b,
-/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140,
-/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
-/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
-/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
-/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
-/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
-/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
-/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
-/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
-/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7,
-/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004,
-/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
-/* NULLALGORITHM */
-/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
-/* HFGEXECCHILD */
-/* 0167 */ 0x00000000,0x000eba44,
-/* HFGEXECCHILD_98 */
-/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-/* HFGEXECCHILD_PUSH1IND */
-/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 016C */ 0x00006a88,0x000c75c4,
-/* HFGEXECSIBLING */
-/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
-/* HFGEXECSIBLING_298 */
-/* 016F */ 0x00087401,0x000e4782,
-/* HFGEXECSIBLING_2IND1 */
-/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0172 */ 0x00006a88,0x000c75c4,
-/* S16_CODECOUTPUTTASK */
-/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
-/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
-/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
-/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
-/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c,
-/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
-/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
-/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
-/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
-/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
-/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
-/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
-/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
-/* 018D */ 0x00048f05,0x00000000
-};
-/* #CODE_END */
-
-static u32 cwcemb80_parameter[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000,
-/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000,
-/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000,
-/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2,
-/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000,
-/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d,
-/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000,
-/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a,
-/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3,
-/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000,
-/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2,
-/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff,
-/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0,
-/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000,
-/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9,
-/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff,
-/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780,
-/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000,
-/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9,
-/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1,
-/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000,
-/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004,
-/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610,
-/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d,
-/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136,
-/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000,
-/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000
-}; /* #PARAMETER_END */
-
-static u32 cwcemb80_sample[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004
-}; /* #SAMPLE_END */
-
-
-static struct dsp_segment_desc cwcemb80_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code },
-  { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter },
-  { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample },
-};
-
-static struct dsp_module_desc cwcemb80_module = {
-  "cwcemb80",
-  {
-    38,
-    cwcemb80_symbols
-  },
-  3,
-  cwcemb80_segments,
-};
-
-#endif /* __HEADER_cwcemb80_H__ */
index 8e7fe033270fcbc8857482f621e0cf7aa0f43fa3..87078d3a68549b931afed8a7cb09a259ebd883a1 100644 (file)
@@ -56,6 +56,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/darla20_dsp.fw");
+
 #define FW_DARLA20_DSP 0
 
 static const struct firmware card_fw[] = {
index a13c623eb999f2988b7f26f994640730dda56092..42b48f9d21286113915fd5439d83a4e1614b6d8e 100644 (file)
@@ -60,6 +60,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/darla24_dsp.fw");
+
 #define FW_DARLA24_DSP 0
 
 static const struct firmware card_fw[] = {
index 8fb15823aca569ae6249e36bba4e0a2da6a8236d..8dbb7ac865c1952e680ad0e0c092c46a72db6faa 100644 (file)
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/echo3g_dsp.fw");
+MODULE_FIRMWARE("ea/3g_asic.fw");
+
 #define FW_361_LOADER  0
 #define FW_ECHO3G_DSP  1
 #define FW_3G_ASIC     2
index e413da00759bcbe3cc2e67086b41866d12e4bc4a..f27b6a733b96a50d1a51a1ca5653601a58f0a554 100644 (file)
@@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        struct audiopipe *pipe = runtime->private_data;
        int i, err;
        u32 channelmask = 0;
-       struct list_head *pos;
        struct snd_pcm_substream *s;
 
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                for (i = 0; i < DSP_MAXPIPES; i++) {
                        if (s == chip->substream[i]) {
                                channelmask |= 1 << i;
index 9f439ea459f4a552dacd0b844919e017cadd16f9..52a933189576ad5a2f1060347af38dc5d88786d7 100644 (file)
@@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip)
 
        chip->asic_code = &card_fw[FW_3G_ASIC];
 
-       /* Now give the new ASIC a little time to set up */
-       mdelay(2);
+       /* Now give the new ASIC some time to set up */
+       msleep(1000);
        /* See if it worked */
        box_type = check_asic_status(chip);
 
index af4d32026e4ad8302b64d10b7416a4d4f3fb9edb..fee2d483173234cd8f8b988e626d2cc71af98b8b 100644 (file)
@@ -60,6 +60,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/gina20_dsp.fw");
+
 #define FW_GINA20_DSP  0
 
 static const struct firmware card_fw[] = {
index 9ff454a947ed1d697d062c6b6f53344da753e86c..d5eae470fe9a3eff790af608cfd28665e28af418 100644 (file)
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_361_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_asic.fw");
+MODULE_FIRMWARE("ea/gina24_361_asic.fw");
+
 #define FW_361_LOADER          0
 #define FW_GINA24_301_DSP      1
 #define FW_GINA24_361_DSP      2
index 37eb726fd03dddca1e00d0b361937e4af4d99c6b..40f601cd016f32fca593f0b1fe4178052166a690 100644 (file)
@@ -58,6 +58,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dsp.fw");
+
 #define FW_361_LOADER  0
 #define FW_INDIGO_DSP  1
 
index dc8b91824181f8d275efd74d89eb0b409061ba30..771c5383210d23597e9536b55d9a11d22b4af48f 100644 (file)
@@ -58,6 +58,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dj_dsp.fw");
+
 #define FW_361_LOADER          0
 #define FW_INDIGO_DJ_DSP       1
 
index eadf3263453a9e968ed98fad4c9951e2b5188b7f..49c550defcf9230db0ee2fdc6903f21e468d9bb1 100644 (file)
@@ -59,6 +59,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_io_dsp.fw");
+
 #define FW_361_LOADER          0
 #define FW_INDIGO_IO_DSP       1
 
index 6cede497579e9ea8c7855a368905438727b2c24c..8f5483a405ae6922f31671ce43797816ff8b5694 100644 (file)
@@ -66,6 +66,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/layla20_dsp.fw");
+MODULE_FIRMWARE("ea/layla20_asic.fw");
+
 #define FW_LAYLA20_DSP 0
 #define FW_LAYLA20_ASIC        1
 
index 44f735426aa02cffea629c51dd11ea2350932901..0524667c02f700ca7ffdc4fa75ac5a02bddaff4d 100644 (file)
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_1_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2A_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2S_asic.fw");
+
 #define FW_361_LOADER          0
 #define FW_LAYLA24_DSP         1
 #define FW_LAYLA24_1_ASIC      2
index dc172d03ac3ffa08a6eb88888dc6983b4571e873..893c7c20dd70b98eca133c110b7356f705a3e52b 100644 (file)
@@ -66,6 +66,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mia_dsp.fw");
+
 #define FW_361_LOADER  0
 #define FW_MIA_DSP     1
 
index c856ed50dd9a2fc2cfcf76126577de44c0f3c639..3a5d5b0020df30328888a58c3d56d36c015b3c01 100644 (file)
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_dsp.fw");
+MODULE_FIRMWARE("ea/mona_361_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_2_asic.fw");
+
 #define FW_361_LOADER          0
 #define FW_MONA_301_DSP                1
 #define FW_MONA_361_DSP                2
index 80aa585eade4560231c44a320c5649eba3fb2018..dbc805c33fc440795a82b7c339b0750b1c64f21e 100644 (file)
 #include "p17v.h"
 
 
+#define HANA_FILENAME "emu/hana.fw"
+#define DOCK_FILENAME "emu/audio_dock.fw"
+
+MODULE_FIRMWARE(HANA_FILENAME);
+MODULE_FIRMWARE(DOCK_FILENAME);
+
+
 /*************************************************************************
  * EMU10K1 init / done
  *************************************************************************/
@@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
        int tmp,tmp2;
        int reg;
        int err;
-       const char *hana_filename = "emu/hana.fw";
-       const char *dock_filename = "emu/audio_dock.fw";
 
        snd_printk(KERN_INFO "emu1010: Special config.\n");
        /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
@@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
                return -ENODEV;
        }
        snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
-       if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
-               snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
+       if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) {
+               snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME);
                return err;
        }
 
@@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
                /* Return to Audio Dock programming mode */
                snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
                snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
-               if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
+               if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
                        return err;
                }
                snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, 0 );
@@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
         .spi_dac = 1,
         .i2c_adc = 1,
         .spk71 = 1} ,
+       {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
+        .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", 
+        .id = "EMU1010",
+        .emu10k2_chip = 1,
+        .ca0108_chip = 1,
+        .ca_cardbus_chip = 1,
+        .spi_dac = 1,
+        .i2c_adc = 1,
+        .spk71 = 1} ,
        {.vendor = 0x1102, .device = 0x0008, 
         .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
         .id = "Audigy2",
index 465f8d505329b40f48d0d0c219e189df810532c2..7ee19c63c2c8a2114f6d099bacd6051b3ce8482d 100644 (file)
@@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
        struct snd_emu10k1_pcm *epcm;
        int channel;
        int result = 0;
-       struct list_head *pos;
         struct snd_pcm_substream *s;
        u32 basic = 0;
        u32 inte = 0;
@@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
                running = 0;
                break;
        }
-        snd_pcm_group_for_each(pos, substream) {
-                s = snd_pcm_group_substream_entry(pos);
+        snd_pcm_group_for_each_entry(s, substream) {
                runtime = s->runtime;
                epcm = runtime->private_data;
                channel = substream->pcm->device-emu->p16v_device_offset;
index 425b167522d56a087279c18797b5be87df2a5061..6a0ddcf008848422197f2c7dd23eb1e6d66f104f 100644 (file)
@@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
        {
                unsigned int what = 0;
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == ensoniq->playback1_substream) {
                                what |= ES_P1_PAUSE;
                                snd_pcm_trigger_done(s, substream);
@@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_STOP:
        {
                unsigned int what = 0;
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == ensoniq->playback1_substream) {
                                what |= ES_DAC1_EN;
                                snd_pcm_trigger_done(s, substream);
index dc84c189b05f25922e253c4418b71754fba4838d..2faf009076bb81c94aedeee60087adedf0aa7304 100644 (file)
@@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
        runtime->hw = snd_es1968_playback;
        runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
                calc_available_memory_size(chip);
-#if 0
-       snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-                                  1024);
-#endif
+
        spin_lock_irq(&chip->substream_lock);
        list_add(&es->list, &chip->substream_list);
        spin_unlock_irq(&chip->substream_lock);
@@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
        runtime->hw = snd_es1968_capture;
        runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
                calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
-#if 0
-       snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-                                  1024);
-#endif
+       snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
+
        spin_lock_irq(&chip->substream_lock);
        list_add(&es->list, &chip->substream_list);
        spin_unlock_irq(&chip->substream_lock);
index 60d7b05a204a28a26c8cf2dab727454e9b276533..b2484bbdcc1d5e66c1e0fa90163a482c9adef3b9 100644 (file)
@@ -1,5 +1,8 @@
 snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o \
+# since snd-hda-intel is the only driver using hda-codec,
+# merge it into a single module although it was originally
+# designed to be individual modules
+snd-hda-intel-objs += hda_codec.o \
        hda_generic.o \
        patch_realtek.o \
        patch_cmedia.o \
@@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \
        patch_conexant.o \
        patch_via.o
 ifdef CONFIG_PROC_FS
-snd-hda-codec-objs += hda_proc.o
+snd-hda-intel-objs += hda_proc.o
 endif
 
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
index 8f34fb4479837087b177c6f0c15d6eeb29caf300..14649d54b49342bc55b5636fd63c75c1a522a585 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
 
 
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec");
-MODULE_LICENSE("GPL");
-
-
 /*
  * vendor / preset table
  */
@@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = {
  *
  * Returns the obtained response value, or -1 for an error.
  */
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
+unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
+                               int direct,
                                unsigned int verb, unsigned int parm)
 {
        unsigned int res;
        mutex_lock(&codec->bus->cmd_mutex);
-       if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
+       if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
                res = codec->bus->ops.get_response(codec);
        else
                res = (unsigned int)-1;
@@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
        return res;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_read);
-
 /**
  * snd_hda_codec_write - send a single command without waiting for response
  * @codec: the HDA codec
@@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
        return err;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_write);
-
 /**
  * snd_hda_sequence_write - sequence writes
  * @codec: the HDA codec
@@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
                snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
 }
 
-EXPORT_SYMBOL(snd_hda_sequence_write);
-
 /**
  * snd_hda_get_sub_nodes - get the range of sub nodes
  * @codec: the HDA codec
@@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write);
  * Parse the NID and store the start NID of its sub-nodes.
  * Returns the number of sub-nodes.
  */
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id)
+int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
+                         hda_nid_t *start_id)
 {
        unsigned int parm;
 
@@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta
        return (int)(parm & 0x7fff);
 }
 
-EXPORT_SYMBOL(snd_hda_get_sub_nodes);
-
 /**
  * snd_hda_get_connections - get connection list
  * @codec: the HDA codec
@@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
        conn_len = parm & AC_CLIST_LENGTH;
        mask = (1 << (shift-1)) - 1;
 
-       if (! conn_len)
+       if (!conn_len)
                return 0; /* no connection */
 
        if (conn_len == 1) {
                /* single connection */
-               parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0);
+               parm = snd_hda_codec_read(codec, nid, 0,
+                                         AC_VERB_GET_CONNECT_LIST, 0);
                conn_list[0] = parm & mask;
                return 1;
        }
@@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
                if (i % num_elems == 0)
                        parm = snd_hda_codec_read(codec, nid, 0,
                                                  AC_VERB_GET_CONNECT_LIST, i);
-               range_val = !! (parm & (1 << (shift-1))); /* ranges */
+               range_val = !!(parm & (1 << (shift-1))); /* ranges */
                val = parm & mask;
                parm >>= shift;
                if (range_val) {
                        /* ranges between the previous and this one */
-                       if (! prev_nid || prev_nid >= val) {
-                               snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val);
+                       if (!prev_nid || prev_nid >= val) {
+                               snd_printk(KERN_WARNING "hda_codec: "
+                                          "invalid dep_range_val %x:%x\n",
+                                          prev_nid, val);
                                continue;
                        }
                        for (n = prev_nid + 1; n <= val; n++) {
                                if (conns >= max_conns) {
-                                       snd_printk(KERN_ERR "Too many connections\n");
+                                       snd_printk(KERN_ERR
+                                                  "Too many connections\n");
                                        return -EINVAL;
                                }
                                conn_list[conns++] = n;
@@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
        struct hda_bus_unsolicited *unsol;
        unsigned int wp;
 
-       if ((unsol = bus->unsol) == NULL)
+       unsol = bus->unsol;
+       if (!unsol)
                return 0;
 
        wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
@@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_queue_unsol_event);
-
 /*
  * process queueud unsolicited events
  */
@@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work)
                rp <<= 1;
                res = unsol->queue[rp];
                caddr = unsol->queue[rp + 1];
-               if (! (caddr & (1 << 4))) /* no unsolicited event? */
+               if (!(caddr & (1 << 4))) /* no unsolicited event? */
                        continue;
                codec = bus->caddr_tbl[caddr & 0x0f];
                if (codec && codec->patch_ops.unsol_event)
@@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work)
 /*
  * initialize unsolicited queue
  */
-static int init_unsol_queue(struct hda_bus *bus)
+static int __devinit init_unsol_queue(struct hda_bus *bus)
 {
        struct hda_bus_unsolicited *unsol;
 
@@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus)
                return 0;
 
        unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
-       if (! unsol) {
-               snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
+       if (!unsol) {
+               snd_printk(KERN_ERR "hda_codec: "
+                          "can't allocate unsolicited queue\n");
                return -ENOMEM;
        }
        INIT_WORK(&unsol->work, process_unsol_events);
@@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec);
 
 static int snd_hda_bus_free(struct hda_bus *bus)
 {
-       struct list_head *p, *n;
+       struct hda_codec *codec, *n;
 
-       if (! bus)
+       if (!bus)
                return 0;
        if (bus->unsol) {
                flush_scheduled_work();
                kfree(bus->unsol);
        }
-       list_for_each_safe(p, n, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
                snd_hda_codec_free(codec);
        }
        if (bus->ops.private_free)
@@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
-                   struct hda_bus **busp)
+int __devinit snd_hda_bus_new(struct snd_card *card,
+                             const struct hda_bus_template *temp,
+                             struct hda_bus **busp)
 {
        struct hda_bus *bus;
        int err;
@@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
        mutex_init(&bus->cmd_mutex);
        INIT_LIST_HEAD(&bus->codec_list);
 
-       if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
+       err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
+       if (err < 0) {
                snd_hda_bus_free(bus);
                return err;
        }
@@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_bus_new);
-
 /*
  * find a matching codec preset
  */
-static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec)
+static const struct hda_codec_preset __devinit *
+find_codec_preset(struct hda_codec *codec)
 {
        const struct hda_codec_preset **tbl, *preset;
 
+       if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic"))
+               return NULL; /* use the generic parser */
+
        for (tbl = hda_preset_tables; *tbl; tbl++) {
                for (preset = *tbl; preset->id; preset++) {
                        u32 mask = preset->mask;
-                       if (! mask)
+                       if (!mask)
                                mask = ~0;
                        if (preset->id == (codec->vendor_id & mask) &&
-                           (! preset->rev ||
+                           (!preset->rev ||
                             preset->rev == codec->revision_id))
                                return preset;
                }
@@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
                        break;
                }
        }
-       if (! vendor) {
+       if (!vendor) {
                sprintf(tmp, "Generic %04x", vendor_id);
                vendor = tmp;
        }
        if (codec->preset && codec->preset->name)
                snprintf(name, namelen, "%s %s", vendor, codec->preset->name);
        else
-               snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff);
+               snprintf(name, namelen, "%s ID %x", vendor,
+                        codec->vendor_id & 0xffff);
 }
 
 /*
  * look for an AFG and MFG nodes
  */
-static void setup_fg_nodes(struct hda_codec *codec)
+static void __devinit setup_fg_nodes(struct hda_codec *codec)
 {
        int i, total_nodes;
        hda_nid_t nid;
 
        total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
        for (i = 0; i < total_nodes; i++, nid++) {
-               switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
+               unsigned int func;
+               func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE);
+               switch (func & 0xff) {
                case AC_GRP_AUDIO_FUNCTION:
                        codec->afg = nid;
                        break;
@@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
        codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
                                                 &codec->start_nid);
        codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
-       if (! codec->wcaps)
+       if (!codec->wcaps)
                return -ENOMEM;
        nid = codec->start_nid;
        for (i = 0; i < codec->num_nodes; i++, nid++)
@@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
  */
 static void snd_hda_codec_free(struct hda_codec *codec)
 {
-       if (! codec)
+       if (!codec)
                return;
        list_del(&codec->list);
        codec->bus->caddr_tbl[codec->addr] = NULL;
@@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec);
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
-                     struct hda_codec **codecp)
+int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+                               struct hda_codec **codecp)
 {
        struct hda_codec *codec;
        char component[13];
@@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);
 
        if (bus->caddr_tbl[codec_addr]) {
-               snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr);
+               snd_printk(KERN_ERR "hda_codec: "
+                          "address 0x%x is already occupied\n", codec_addr);
                return -EBUSY;
        }
 
@@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        list_add_tail(&codec->list, &bus->codec_list);
        bus->caddr_tbl[codec_addr] = codec;
 
-       codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
+       codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+                                             AC_PAR_VENDOR_ID);
        if (codec->vendor_id == -1)
                /* read again, hopefully the access method was corrected
                 * in the last read...
                 */
                codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
                                                      AC_PAR_VENDOR_ID);
-       codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
-       codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
+       codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+                                                AC_PAR_SUBSYSTEM_ID);
+       codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+                                               AC_PAR_REV_ID);
 
        setup_fg_nodes(codec);
-       if (! codec->afg && ! codec->mfg) {
+       if (!codec->afg && !codec->mfg) {
                snd_printdd("hda_codec: no AFG or MFG node found\n");
                snd_hda_codec_free(codec);
                return -ENODEV;
@@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
                return -ENOMEM;
        }
 
-       if (! codec->subsystem_id) {
+       if (!codec->subsystem_id) {
                hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
-               codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
-                                                        AC_VERB_GET_SUBSYSTEM_ID,
-                                                        0);
+               codec->subsystem_id =
+                       snd_hda_codec_read(codec, nid, 0,
+                                          AC_VERB_GET_SUBSYSTEM_ID, 0);
        }
 
        codec->preset = find_codec_preset(codec);
-       if (! *bus->card->mixername)
+       /* audio codec should override the mixer name */
+       if (codec->afg || !*bus->card->mixername)
                snd_hda_get_codec_name(codec, bus->card->mixername,
                                       sizeof(bus->card->mixername));
 
@@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_new);
-
 /**
  * snd_hda_codec_setup_stream - set up the codec for streaming
  * @codec: the CODEC to set up
@@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new);
  * @channel_id: channel id to pass, zero based.
  * @format: stream format.
  */
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
+void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+                               u32 stream_tag,
                                int channel_id, int format)
 {
-       if (! nid)
+       if (!nid)
                return;
 
-       snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
+       snd_printdd("hda_codec_setup_stream: "
+                   "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
                    nid, stream_tag, channel_id, format);
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
                            (stream_tag << 4) | channel_id);
@@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
 }
 
-EXPORT_SYMBOL(snd_hda_codec_setup_stream);
-
 /*
  * amp access functions
  */
@@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream);
 #define INFO_AMP_VOL(ch)       (1 << (1 + (ch)))
 
 /* initialize the hash table */
-static void init_amp_hash(struct hda_codec *codec)
+static void __devinit init_amp_hash(struct hda_codec *codec)
 {
        memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
        codec->num_amp_entries = 0;
@@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
        if (codec->num_amp_entries >= codec->amp_info_size) {
                /* reallocate the array */
                int new_size = codec->amp_info_size + 64;
-               struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
-                                                       GFP_KERNEL);
-               if (! new_info) {
-                       snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");
+               struct hda_amp_info *new_info;
+               new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
+                                  GFP_KERNEL);
+               if (!new_info) {
+                       snd_printk(KERN_ERR "hda_codec: "
+                                  "can't malloc amp_info\n");
                        return NULL;
                }
                if (codec->amp_info) {
                        memcpy(new_info, codec->amp_info,
-                              codec->amp_info_size * sizeof(struct hda_amp_info));
+                              codec->amp_info_size *
+                              sizeof(struct hda_amp_info));
                        kfree(codec->amp_info);
                }
                codec->amp_info_size = new_size;
@@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
  */
 static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
 {
-       struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+       struct hda_amp_info *info;
 
-       if (! info)
+       info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+       if (!info)
                return 0;
-       if (! (info->status & INFO_AMP_CAPS)) {
-               if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
+       if (!(info->status & INFO_AMP_CAPS)) {
+               if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
                        nid = codec->afg;
-               info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
-                                                   AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
+               info->amp_caps = snd_hda_param_read(codec, nid,
+                                                   direction == HDA_OUTPUT ?
+                                                   AC_PAR_AMP_OUT_CAP :
+                                                   AC_PAR_AMP_IN_CAP);
                info->status |= INFO_AMP_CAPS;
        }
        return info->amp_caps;
@@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
  * read the current volume to info
  * if the cache exists, read the cache value.
  */
-static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
-                        hda_nid_t nid, int ch, int direction, int index)
+static unsigned int get_vol_mute(struct hda_codec *codec,
+                                struct hda_amp_info *info, hda_nid_t nid,
+                                int ch, int direction, int index)
 {
        u32 val, parm;
 
@@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
        parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
        parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
        parm |= index;
-       val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);
+       val = snd_hda_codec_read(codec, nid, 0,
+                                AC_VERB_GET_AMP_GAIN_MUTE, parm);
        info->vol[ch] = val & 0xff;
        info->status |= INFO_AMP_VOL(ch);
        return info->vol[ch];
@@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
  * write the current volume in info to the h/w and update the cache
  */
 static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
-                        hda_nid_t nid, int ch, int direction, int index, int val)
+                        hda_nid_t nid, int ch, int direction, int index,
+                        int val)
 {
        u32 parm;
 
@@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
 int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
                           int direction, int index)
 {
-       struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
-       if (! info)
+       struct hda_amp_info *info;
+       info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
+       if (!info)
                return 0;
        return get_vol_mute(codec, info, nid, ch, direction, index);
 }
@@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
 int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
                             int direction, int idx, int mask, int val)
 {
-       struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+       struct hda_amp_info *info;
 
-       if (! info)
+       info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+       if (!info)
                return 0;
        val &= mask;
        val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
-       if (info->vol[ch] == val && ! codec->in_resume)
+       if (info->vol[ch] == val && !codec->in_resume)
                return 0;
        put_vol_mute(codec, info, nid, ch, direction, idx, val);
        return 1;
@@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
 #define get_amp_index(kc)      (((kc)->private_value >> 19) & 0xf)
 
 /* volume */
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_info *uinfo)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        u16 nid = get_amp_nid(kcontrol);
@@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
        u32 caps;
 
        caps = query_amp_caps(codec, nid, dir);
-       caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */
-       if (! caps) {
-               printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid);
+       /* num steps */
+       caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
+       if (!caps) {
+               printk(KERN_WARNING "hda_codec: "
+                      "num_steps = 0 for NID=0x%x\n", nid);
                return -EINVAL;
        }
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
        return 0;
 }
 
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = get_amp_nid(kcontrol);
@@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        return 0;
 }
 
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = get_amp_nid(kcontrol);
@@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
        if (size < 4 * sizeof(unsigned int))
                return -ENOMEM;
        caps = query_amp_caps(codec, nid, dir);
-       val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25;
+       val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
+       val2 = (val2 + 1) * 25;
        val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
        val1 = ((int)val1) * ((int)val2);
        if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
@@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 }
 
 /* switch */
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_info *uinfo)
 {
        int chs = get_amp_channels(kcontrol);
 
@@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
        return 0;
 }
 
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = get_amp_nid(kcontrol);
@@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
        long *valp = ucontrol->value.integer.value;
 
        if (chs & 1)
-               *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1;
+               *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
+                          0x80) ? 0 : 1;
        if (chs & 2)
-               *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1;
+               *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
+                        0x80) ? 0 : 1;
        return 0;
 }
 
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = get_amp_nid(kcontrol);
@@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 #define AMP_VAL_IDX_SHIFT      19
 #define AMP_VAL_IDX_MASK       (0x0f<<19)
 
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        unsigned long pval;
@@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
        return err;
 }
 
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        unsigned long pval;
@@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
        pval = kcontrol->private_value;
        indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
        for (i = 0; i < indices; i++) {
-               kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+               kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) |
+                       (i << AMP_VAL_IDX_SHIFT);
                err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
                if (err < 0)
                        break;
@@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
  * SPDIF out controls
  */
 
-static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_info *uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
        uinfo->count = 1;
        return 0;
 }
 
-static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
 {
        ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
                                           IEC958_AES0_NONAUDIO |
@@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
        return 0;
 }
 
-static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
 {
        ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
                                           IEC958_AES0_NONAUDIO |
@@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
        return 0;
 }
 
-static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits)
        unsigned short val = 0;
 
        if (sbits & IEC958_AES0_PROFESSIONAL)
-               val |= 1 << 6;
+               val |= AC_DIG1_PROFESSIONAL;
        if (sbits & IEC958_AES0_NONAUDIO)
-               val |= 1 << 5;
+               val |= AC_DIG1_NONAUDIO;
        if (sbits & IEC958_AES0_PROFESSIONAL) {
-               if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
-                       val |= 1 << 3;
+               if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
+                   IEC958_AES0_PRO_EMPHASIS_5015)
+                       val |= AC_DIG1_EMPHASIS;
        } else {
-               if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
-                       val |= 1 << 3;
-               if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
-                       val |= 1 << 4;
+               if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
+                   IEC958_AES0_CON_EMPHASIS_5015)
+                       val |= AC_DIG1_EMPHASIS;
+               if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
+                       val |= AC_DIG1_COPYRIGHT;
                if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
-                       val |= 1 << 7;
+                       val |= AC_DIG1_LEVEL;
                val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
        }
        return val;
@@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val)
 {
        unsigned int sbits = 0;
 
-       if (val & (1 << 5))
+       if (val & AC_DIG1_NONAUDIO)
                sbits |= IEC958_AES0_NONAUDIO;
-       if (val & (1 << 6))
+       if (val & AC_DIG1_PROFESSIONAL)
                sbits |= IEC958_AES0_PROFESSIONAL;
        if (sbits & IEC958_AES0_PROFESSIONAL) {
-               if (sbits & (1 << 3))
+               if (sbits & AC_DIG1_EMPHASIS)
                        sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
        } else {
-               if (val & (1 << 3))
+               if (val & AC_DIG1_EMPHASIS)
                        sbits |= IEC958_AES0_CON_EMPHASIS_5015;
-               if (! (val & (1 << 4)))
+               if (!(val & AC_DIG1_COPYRIGHT))
                        sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
-               if (val & (1 << 7))
+               if (val & AC_DIG1_LEVEL)
                        sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
                sbits |= val & (0x7f << 8);
        }
        return sbits;
 }
 
-static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = kcontrol->private_value;
@@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c
        codec->spdif_ctls = val;
 
        if (change || codec->in_resume) {
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                   val & 0xff);
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2,
+                                   val >> 8);
        }
 
        mutex_unlock(&codec->spdif_mutex);
        return change;
 }
 
-static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_info *uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
        uinfo->count = 1;
@@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s
        return 0;
 }
 
-static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
-       ucontrol->value.integer.value[0] = codec->spdif_ctls & 1;
+       ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE;
        return 0;
 }
 
-static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = kcontrol->private_value;
@@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
        int change;
 
        mutex_lock(&codec->spdif_mutex);
-       val = codec->spdif_ctls & ~1;
+       val = codec->spdif_ctls & ~AC_DIG1_ENABLE;
        if (ucontrol->value.integer.value[0])
-               val |= 1;
+               val |= AC_DIG1_ENABLE;
        change = codec->spdif_ctls != val;
        if (change || codec->in_resume) {
                codec->spdif_ctls = val;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                                   AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
-                                   AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                   val & 0xff);
+               /* unmute amp switch (if any) */
+               if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
+                   (val & AC_DIG1_ENABLE))
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_AMP_GAIN_MUTE,
+                                           AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
+                                           AC_AMP_SET_OUTPUT);
        }
        mutex_unlock(&codec->spdif_mutex);
        return change;
@@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
+                                           hda_nid_t nid)
 {
        int err;
        struct snd_kcontrol *kctl;
@@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
        for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
                kctl->private_value = nid;
-               if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+               err = snd_ctl_add(codec->bus->card, kctl);
+               if (err < 0)
                        return err;
        }
-       codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
+       codec->spdif_ctls =
+               snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
        codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
        return 0;
 }
@@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
 
 #define snd_hda_spdif_in_switch_info   snd_hda_spdif_out_switch_info
 
-static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd
        return 0;
 }
 
-static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = kcontrol->private_value;
@@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd
        change = codec->spdif_in_enable != val;
        if (change || codec->in_resume) {
                codec->spdif_in_enable = val;
-               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                   val);
        }
        mutex_unlock(&codec->spdif_mutex);
        return change;
 }
 
-static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
+                                      struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = kcontrol->private_value;
@@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
+                                          hda_nid_t nid)
 {
        int err;
        struct snd_kcontrol *kctl;
@@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
        for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
                kctl->private_value = nid;
-               if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+               err = snd_ctl_add(codec->bus->card, kctl);
+               if (err < 0)
                        return err;
        }
-       codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1;
+       codec->spdif_in_enable =
+               snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) &
+               AC_DIG1_ENABLE;
        return 0;
 }
 
@@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
  *
  * Returns 0 if successful, otherwise a negative error code.
  */
-int snd_hda_build_controls(struct hda_bus *bus)
+int __devinit snd_hda_build_controls(struct hda_bus *bus)
 {
-       struct list_head *p;
+       struct hda_codec *codec;
 
        /* build controls */
-       list_for_each(p, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &bus->codec_list, list) {
                int err;
-               if (! codec->patch_ops.build_controls)
+               if (!codec->patch_ops.build_controls)
                        continue;
                err = codec->patch_ops.build_controls(codec);
                if (err < 0)
@@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus)
        }
 
        /* initialize */
-       list_for_each(p, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &bus->codec_list, list) {
                int err;
                hda_set_power_state(codec,
                                    codec->afg ? codec->afg : codec->mfg,
                                    AC_PWRST_D0);
-               if (! codec->patch_ops.init)
+               if (!codec->patch_ops.init)
                        continue;
                err = codec->patch_ops.init(codec);
                if (err < 0)
@@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus)
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_build_controls);
-
 /*
  * stream formats
  */
@@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = {
        { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
        { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
        { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
+#define AC_PAR_PCM_RATE_BITS   11
+       /* up to bits 10, 384kHZ isn't supported properly */
+
+       /* not autodetected value */
+       { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
 
        { 0 } /* terminator */
 };
@@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
                        val = rate_bits[i].hda_fmt;
                        break;
                }
-       if (! rate_bits[i].hz) {
+       if (!rate_bits[i].hz) {
                snd_printdd("invalid rate %d\n", rate);
                return 0;
        }
@@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
                        val |= 0x20;
                break;
        default:
-               snd_printdd("invalid format width %d\n", snd_pcm_format_width(format));
+               snd_printdd("invalid format width %d\n",
+                           snd_pcm_format_width(format));
                return 0;
        }
 
        return val;
 }
 
-EXPORT_SYMBOL(snd_hda_calc_stream_format);
-
 /**
  * snd_hda_query_supported_pcm - query the supported PCM rates and formats
  * @codec: the HDA codec
@@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                if (val == -1)
                        return -EIO;
        }
-       if (! val)
+       if (!val)
                val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
 
        if (ratesp) {
                u32 rates = 0;
-               for (i = 0; rate_bits[i].hz; i++) {
+               for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
                        if (val & (1 << i))
                                rates |= rate_bits[i].alsa_bits;
                }
@@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
                if (streams == -1)
                        return -EIO;
-               if (! streams) {
-                       streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
+               if (!streams) {
+                       streams = snd_hda_param_read(codec, codec->afg,
+                                                    AC_PAR_STREAM);
                        if (streams == -1)
                                return -EIO;
                }
@@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                                        bps = 24;
                                else if (val & AC_SUPPCM_BITS_20)
                                        bps = 20;
-                       } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) {
+                       } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
+                                         AC_SUPPCM_BITS_32)) {
                                formats |= SNDRV_PCM_FMTBIT_S32_LE;
                                if (val & AC_SUPPCM_BITS_32)
                                        bps = 32;
@@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
                                        bps = 20;
                        }
                }
-               else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */
+               else if (streams == AC_SUPFMT_FLOAT32) {
+                       /* should be exclusive */
                        formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
                        bps = 32;
-               } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */
+               } else if (streams == AC_SUPFMT_AC3) {
+                       /* should be exclusive */
                        /* temporary hack: we have still no proper support
                         * for the direct AC3 stream...
                         */
@@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 }
 
 /**
- * snd_hda_is_supported_format - check whether the given node supports the format val
+ * snd_hda_is_supported_format - check whether the given node supports
+ * the format val
  *
  * Returns 1 if supported, 0 if not.
  */
@@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
                if (val == -1)
                        return 0;
        }
-       if (! val) {
+       if (!val) {
                val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
                if (val == -1)
                        return 0;
        }
 
        rate = format & 0xff00;
-       for (i = 0; rate_bits[i].hz; i++)
+       for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
                if (rate_bits[i].hda_fmt == rate) {
                        if (val & (1 << i))
                                break;
                        return 0;
                }
-       if (! rate_bits[i].hz)
+       if (i >= AC_PAR_PCM_RATE_BITS)
                return 0;
 
        stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
        if (stream == -1)
                return 0;
-       if (! stream && nid != codec->afg)
+       if (!stream && nid != codec->afg)
                stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
-       if (! stream || stream == -1)
+       if (!stream || stream == -1)
                return 0;
 
        if (stream & AC_SUPFMT_PCM) {
                switch (format & 0xf0) {
                case 0x00:
-                       if (! (val & AC_SUPPCM_BITS_8))
+                       if (!(val & AC_SUPPCM_BITS_8))
                                return 0;
                        break;
                case 0x10:
-                       if (! (val & AC_SUPPCM_BITS_16))
+                       if (!(val & AC_SUPPCM_BITS_16))
                                return 0;
                        break;
                case 0x20:
-                       if (! (val & AC_SUPPCM_BITS_20))
+                       if (!(val & AC_SUPPCM_BITS_20))
                                return 0;
                        break;
                case 0x30:
-                       if (! (val & AC_SUPPCM_BITS_24))
+                       if (!(val & AC_SUPPCM_BITS_24))
                                return 0;
                        break;
                case 0x40:
-                       if (! (val & AC_SUPPCM_BITS_32))
+                       if (!(val & AC_SUPPCM_BITS_32))
                                return 0;
                        break;
                default:
@@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
        return 0;
 }
 
-static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info)
+static int __devinit set_pcm_default_values(struct hda_codec *codec,
+                                           struct hda_pcm_stream *info)
 {
-       if (info->nid) {
-               /* query support PCM information from the given NID */
-               if (! info->rates || ! info->formats)
-                       snd_hda_query_supported_pcm(codec, info->nid,
-                                                   info->rates ? NULL : &info->rates,
-                                                   info->formats ? NULL : &info->formats,
-                                                   info->maxbps ? NULL : &info->maxbps);
+       /* query support PCM information from the given NID */
+       if (info->nid && (!info->rates || !info->formats)) {
+               snd_hda_query_supported_pcm(codec, info->nid,
+                               info->rates ? NULL : &info->rates,
+                               info->formats ? NULL : &info->formats,
+                               info->maxbps ? NULL : &info->maxbps);
        }
        if (info->ops.open == NULL)
                info->ops.open = hda_pcm_default_open_close;
@@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream
  *
  * This function returns 0 if successfull, or a negative error code.
  */
-int snd_hda_build_pcms(struct hda_bus *bus)
+int __devinit snd_hda_build_pcms(struct hda_bus *bus)
 {
-       struct list_head *p;
+       struct hda_codec *codec;
 
-       list_for_each(p, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &bus->codec_list, list) {
                unsigned int pcm, s;
                int err;
-               if (! codec->patch_ops.build_pcms)
+               if (!codec->patch_ops.build_pcms)
                        continue;
                err = codec->patch_ops.build_pcms(codec);
                if (err < 0)
@@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus)
                        for (s = 0; s < 2; s++) {
                                struct hda_pcm_stream *info;
                                info = &codec->pcm_info[pcm].stream[s];
-                               if (! info->substreams)
+                               if (!info->substreams)
                                        continue;
                                err = set_pcm_default_values(codec, info);
                                if (err < 0)
@@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus)
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_build_pcms);
-
 /**
  * snd_hda_check_board_config - compare the current codec with the config table
  * @codec: the HDA codec
@@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
  *
  * If no entries are matching, the function returns a negative value.
  */
-int snd_hda_check_board_config(struct hda_codec *codec,
-                              int num_configs, const char **models,
-                              const struct snd_pci_quirk *tbl)
+int __devinit snd_hda_check_board_config(struct hda_codec *codec,
+                                        int num_configs, const char **models,
+                                        const struct snd_pci_quirk *tbl)
 {
        if (codec->bus->modelname && models) {
                int i;
@@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec,
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+int __devinit snd_hda_add_new_ctls(struct hda_codec *codec,
+                                  struct snd_kcontrol_new *knew)
 {
        int err;
 
        for (; knew->name; knew++) {
                struct snd_kcontrol *kctl;
                kctl = snd_ctl_new1(knew, codec);
-               if (! kctl)
+               if (!kctl)
                        return -ENOMEM;
                err = snd_ctl_add(codec->bus->card, kctl);
                if (err < 0) {
-                       if (! codec->addr)
+                       if (!codec->addr)
                                return err;
                        kctl = snd_ctl_new1(knew, codec);
-                       if (! kctl)
+                       if (!kctl)
                                return -ENOMEM;
                        kctl->id.device = codec->addr;
-                       if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+                       err = snd_ctl_add(codec->bus->card, kctl);
+                       if (err < 0)
                                return err;
                }
        }
@@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 /*
  * Channel mode helper
  */
-int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
-                        const struct hda_channel_mode *chmode, int num_chmodes)
+int snd_hda_ch_mode_info(struct hda_codec *codec,
+                        struct snd_ctl_elem_info *uinfo,
+                        const struct hda_channel_mode *chmode,
+                        int num_chmodes)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
        uinfo->count = 1;
@@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf
        return 0;
 }
 
-int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
-                       const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_get(struct hda_codec *codec,
+                       struct snd_ctl_elem_value *ucontrol,
+                       const struct hda_channel_mode *chmode,
+                       int num_chmodes,
                        int max_channels)
 {
        int i;
@@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
        return 0;
 }
 
-int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
-                       const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_put(struct hda_codec *codec,
+                       struct snd_ctl_elem_value *ucontrol,
+                       const struct hda_channel_mode *chmode,
+                       int num_chmodes,
                        int *max_channelsp)
 {
        unsigned int mode;
 
        mode = ucontrol->value.enumerated.item[0];
        snd_assert(mode < num_chmodes, return -EINVAL);
-       if (*max_channelsp == chmode[mode].channels && ! codec->in_resume)
+       if (*max_channelsp == chmode[mode].channels && !codec->in_resume)
                return 0;
        /* change the current channel setting */
        *max_channelsp = chmode[mode].channels;
@@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
 /*
  * input MUX helper
  */
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo)
+int snd_hda_input_mux_info(const struct hda_input_mux *imux,
+                          struct snd_ctl_elem_info *uinfo)
 {
        unsigned int index;
 
@@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem
        return 0;
 }
 
-int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
-                         struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
+int snd_hda_input_mux_put(struct hda_codec *codec,
+                         const struct hda_input_mux *imux,
+                         struct snd_ctl_elem_value *ucontrol,
+                         hda_nid_t nid,
                          unsigned int *cur_val)
 {
        unsigned int idx;
@@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && ! codec->in_resume)
+       if (*cur_val == idx && !codec->in_resume)
                return 0;
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
                            imux->items[idx].index);
@@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
  * Multi-channel / digital-out PCM helper functions
  */
 
+/* setup SPDIF output stream */
+static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
+                                unsigned int stream_tag, unsigned int format)
+{
+       /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
+       if (codec->spdif_ctls & AC_DIG1_ENABLE)
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                   codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+       snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+       /* turn on again (if needed) */
+       if (codec->spdif_ctls & AC_DIG1_ENABLE)
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+                                   codec->spdif_ctls & 0xff);
+}
+
 /*
  * open the digital out in the exclusive mode
  */
-int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_open(struct hda_codec *codec,
+                              struct hda_multi_out *mout)
 {
        mutex_lock(&codec->spdif_mutex);
-       if (mout->dig_out_used) {
-               mutex_unlock(&codec->spdif_mutex);
-               return -EBUSY; /* already being used */
-       }
+       if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
+               /* already opened as analog dup; reset it once */
+               snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
        mout->dig_out_used = HDA_DIG_EXCLUSIVE;
        mutex_unlock(&codec->spdif_mutex);
        return 0;
 }
 
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+                                 struct hda_multi_out *mout,
+                                 unsigned int stream_tag,
+                                 unsigned int format,
+                                 struct snd_pcm_substream *substream)
+{
+       mutex_lock(&codec->spdif_mutex);
+       setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
+       mutex_unlock(&codec->spdif_mutex);
+       return 0;
+}
+
 /*
  * release the digital out
  */
-int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_close(struct hda_codec *codec,
+                               struct hda_multi_out *mout)
 {
        mutex_lock(&codec->spdif_mutex);
        mout->dig_out_used = 0;
@@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m
 /*
  * set up more restrictions for analog out
  */
-int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+                                 struct hda_multi_out *mout,
                                  struct snd_pcm_substream *substream)
 {
        substream->runtime->hw.channels_max = mout->max_channels;
@@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out
  * set up the i/o for analog out
  * when the digital out is available, copy the front out to digital out, too.
  */
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
+                                    struct hda_multi_out *mout,
                                     unsigned int stream_tag,
                                     unsigned int format,
                                     struct snd_pcm_substream *substream)
@@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
        mutex_lock(&codec->spdif_mutex);
        if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
                if (chs == 2 &&
-                   snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
-                   ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
+                   snd_hda_is_supported_format(codec, mout->dig_out_nid,
+                                               format) &&
+                   !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
                        mout->dig_out_used = HDA_DIG_ANALOG_DUP;
-                       /* setup digital receiver */
-                       snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
-                                                  stream_tag, 0, format);
+                       setup_dig_out_stream(codec, mout->dig_out_nid,
+                                            stream_tag, format);
                } else {
                        mout->dig_out_used = 0;
-                       snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
+                       snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+                                                  0, 0, 0);
                }
        }
        mutex_unlock(&codec->spdif_mutex);
 
        /* front */
-       snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
+       snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
+                                  0, format);
        if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
                /* headphone out will just decode front left/right (stereo) */
-               snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
+               snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
+                                          0, format);
        /* extra outputs copied from front */
        for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
                if (mout->extra_out_nid[i])
@@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
        /* surrounds */
        for (i = 1; i < mout->num_dacs; i++) {
                if (chs >= (i + 1) * 2) /* independent out */
-                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
-                                                  format);
+                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+                                                  i * 2, format);
                else /* copy front */
-                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
-                                                  format);
+                       snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+                                                  0, format);
        }
        return 0;
 }
@@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
 /*
  * clean up the setting for analog out
  */
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
+                                    struct hda_multi_out *mout)
 {
        hda_nid_t *nids = mout->dac_nids;
        int i;
@@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o
  * Helper for automatic ping configuration
  */
 
-static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
+static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
 {
        for (; *list; list++)
                if (*list == nid)
@@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
        return 0;
 }
 
+
+/*
+ * Sort an associated group of pins according to their sequence numbers.
+ */
+static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
+                                 int num_pins)
+{
+       int i, j;
+       short seq;
+       hda_nid_t nid;
+       
+       for (i = 0; i < num_pins; i++) {
+               for (j = i + 1; j < num_pins; j++) {
+                       if (sequences[i] > sequences[j]) {
+                               seq = sequences[i];
+                               sequences[i] = sequences[j];
+                               sequences[j] = seq;
+                               nid = pins[i];
+                               pins[i] = pins[j];
+                               pins[j] = nid;
+                       }
+               }
+       }
+}
+
+
 /*
  * Parse all pin widgets and store the useful pin nids to cfg
  *
@@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
  * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
  * respectively.
  */
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
-                                hda_nid_t *ignore_nids)
+int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec,
+                                          struct auto_pin_cfg *cfg,
+                                          hda_nid_t *ignore_nids)
 {
        hda_nid_t nid, nid_start;
-       int i, j, nodes;
-       short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
+       int nodes;
+       short seq, assoc_line_out, assoc_speaker;
+       short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
+       short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
 
        memset(cfg, 0, sizeof(*cfg));
 
-       memset(sequences, 0, sizeof(sequences));
-       assoc_line_out = 0;
+       memset(sequences_line_out, 0, sizeof(sequences_line_out));
+       memset(sequences_speaker, 0, sizeof(sequences_speaker));
+       assoc_line_out = assoc_speaker = 0;
 
        nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
        for (nid = nid_start; nid < nodes + nid_start; nid++) {
                unsigned int wid_caps = get_wcaps(codec, nid);
-               unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+               unsigned int wid_type =
+                       (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
                unsigned int def_conf;
                short assoc, loc;
 
@@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
                if (ignore_nids && is_in_nid_list(nid, ignore_nids))
                        continue;
 
-               def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+               def_conf = snd_hda_codec_read(codec, nid, 0,
+                                             AC_VERB_GET_CONFIG_DEFAULT, 0);
                if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
                        continue;
                loc = get_defcfg_location(def_conf);
@@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
                case AC_JACK_LINE_OUT:
                        seq = get_defcfg_sequence(def_conf);
                        assoc = get_defcfg_association(def_conf);
-                       if (! assoc)
+                       if (!assoc)
                                continue;
-                       if (! assoc_line_out)
+                       if (!assoc_line_out)
                                assoc_line_out = assoc;
                        else if (assoc_line_out != assoc)
                                continue;
                        if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
                                continue;
                        cfg->line_out_pins[cfg->line_outs] = nid;
-                       sequences[cfg->line_outs] = seq;
+                       sequences_line_out[cfg->line_outs] = seq;
                        cfg->line_outs++;
                        break;
                case AC_JACK_SPEAKER:
+                       seq = get_defcfg_sequence(def_conf);
+                       assoc = get_defcfg_association(def_conf);
+                       if (! assoc)
+                               continue;
+                       if (! assoc_speaker)
+                               assoc_speaker = assoc;
+                       else if (assoc_speaker != assoc)
+                               continue;
                        if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
                                continue;
                        cfg->speaker_pins[cfg->speaker_outs] = nid;
+                       sequences_speaker[cfg->speaker_outs] = seq;
                        cfg->speaker_outs++;
                        break;
                case AC_JACK_HP_OUT:
@@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
        }
 
        /* sort by sequence */
-       for (i = 0; i < cfg->line_outs; i++)
-               for (j = i + 1; j < cfg->line_outs; j++)
-                       if (sequences[i] > sequences[j]) {
-                               seq = sequences[i];
-                               sequences[i] = sequences[j];
-                               sequences[j] = seq;
-                               nid = cfg->line_out_pins[i];
-                               cfg->line_out_pins[i] = cfg->line_out_pins[j];
-                               cfg->line_out_pins[j] = nid;
-                       }
+       sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
+                             cfg->line_outs);
+       sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
+                             cfg->speaker_outs);
+       
+       /*
+        * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
+        * as a primary output
+        */
+       if (!cfg->line_outs) {
+               if (cfg->speaker_outs) {
+                       cfg->line_outs = cfg->speaker_outs;
+                       memcpy(cfg->line_out_pins, cfg->speaker_pins,
+                              sizeof(cfg->speaker_pins));
+                       cfg->speaker_outs = 0;
+                       memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
+                       cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
+               } else if (cfg->hp_outs) {
+                       cfg->line_outs = cfg->hp_outs;
+                       memcpy(cfg->line_out_pins, cfg->hp_pins,
+                              sizeof(cfg->hp_pins));
+                       cfg->hp_outs = 0;
+                       memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+                       cfg->line_out_type = AUTO_PIN_HP_OUT;
+               }
+       }
 
        /* Reorder the surround channels
         * ALSA sequence is front/surr/clfe/side
         * HDA sequence is:
         *    4-ch: front/surr  =>  OK as it is
         *    6-ch: front/clfe/surr
-        *    8-ch: front/clfe/side/surr
+        *    8-ch: front/clfe/rear/side|fc
         */
        switch (cfg->line_outs) {
        case 3:
-               nid = cfg->line_out_pins[1];
-               cfg->line_out_pins[1] = cfg->line_out_pins[2];
-               cfg->line_out_pins[2] = nid;
-               break;
        case 4:
                nid = cfg->line_out_pins[1];
-               cfg->line_out_pins[1] = cfg->line_out_pins[3];
-               cfg->line_out_pins[3] = cfg->line_out_pins[2];
+               cfg->line_out_pins[1] = cfg->line_out_pins[2];
                cfg->line_out_pins[2] = nid;
                break;
        }
@@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
                   cfg->input_pins[AUTO_PIN_CD],
                   cfg->input_pins[AUTO_PIN_AUX]);
 
-       /*
-        * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
-        * as a primary output
-        */
-       if (! cfg->line_outs) {
-               if (cfg->speaker_outs) {
-                       cfg->line_outs = cfg->speaker_outs;
-                       memcpy(cfg->line_out_pins, cfg->speaker_pins,
-                              sizeof(cfg->speaker_pins));
-                       cfg->speaker_outs = 0;
-                       memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
-               } else if (cfg->hp_outs) {
-                       cfg->line_outs = cfg->hp_outs;
-                       memcpy(cfg->line_out_pins, cfg->hp_pins,
-                              sizeof(cfg->hp_pins));
-                       cfg->hp_outs = 0;
-                       memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
-               }
-       }
-
        return 0;
 }
 
@@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
  */
 int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
 {
-       struct list_head *p;
+       struct hda_codec *codec;
 
        /* FIXME: should handle power widget capabilities */
-       list_for_each(p, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &bus->codec_list, list) {
                if (codec->patch_ops.suspend)
                        codec->patch_ops.suspend(codec, state);
                hda_set_power_state(codec,
@@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_suspend);
-
 /**
  * snd_hda_resume - resume the codecs
  * @bus: the HDA bus
@@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend);
  */
 int snd_hda_resume(struct hda_bus *bus)
 {
-       struct list_head *p;
+       struct hda_codec *codec;
 
-       list_for_each(p, &bus->codec_list) {
-               struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+       list_for_each_entry(codec, &bus->codec_list, list) {
                hda_set_power_state(codec,
                                    codec->afg ? codec->afg : codec->mfg,
                                    AC_PWRST_D0);
@@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus)
        return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_resume);
-
 /**
  * snd_hda_resume_ctls - resume controls in the new control list
  * @codec: the HDA codec
@@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
        struct snd_ctl_elem_value *val;
 
        val = kmalloc(sizeof(*val), GFP_KERNEL);
-       if (! val)
+       if (!val)
                return -ENOMEM;
        codec->in_resume = 1;
        for (; knew->name; knew++) {
@@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec)
        return snd_hda_resume_ctls(codec, dig_in_ctls);
 }
 #endif
-
-/*
- *  INIT part
- */
-
-static int __init alsa_hda_init(void)
-{
-       return 0;
-}
-
-static void __exit alsa_hda_exit(void)
-{
-}
-
-module_init(alsa_hda_init)
-module_exit(alsa_hda_exit)
index c12bc4e8840f04d0b7443646485d1e641f8b0430..56c26e7ccdf118618281b95f81578516437fa869 100644 (file)
@@ -233,7 +233,7 @@ enum {
  */
 
 /* Amp gain/mute */
-#define AC_AMP_MUTE                    (1<<8)
+#define AC_AMP_MUTE                    (1<<7)
 #define AC_AMP_GAIN                    (0x7f)
 #define AC_AMP_GET_INDEX               (0xf<<0)
 
index 1e5ff0cd37098cc5877fbf6495f870cf1d438b9f..000287f7da43018461026f796d8a22d475eaef0a 100644 (file)
@@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
                        return -ENOMEM;
                }
        }
-       memcpy(node->conn_list, conn_list, nconns);
+       memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
        node->nconns = nconns;
        node->wid_caps = get_wcaps(codec, nid);
        node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
index 1672cace1ae7d55592a1088a97511efe9761d4c0..2fa281cbef91c5698ef10c6df3ee6a7958db69b0 100644 (file)
@@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{ATI, SB600},"
                         "{ATI, RS600},"
                         "{ATI, RS690},"
+                        "{ATI, RS780},"
+                        "{ATI, R600},"
                         "{VIA, VT8251},"
                         "{VIA, VT8237A},"
                         "{SiS, SIS966},"
@@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define RIRB_INT_MASK          0x05
 
 /* STATESTS int mask: SD2,SD1,SD0 */
+#define AZX_MAX_CODECS         3
 #define STATESTS_INT_MASK      0x07
 
 /* SD_CTL bits */
@@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
 static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
        struct hda_bus_template bus_temp;
-       int c, codecs, err;
+       int c, codecs, audio_codecs, err;
 
        memset(&bus_temp, 0, sizeof(bus_temp));
        bus_temp.private_data = chip;
@@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
        if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
                return err;
 
-       codecs = 0;
-       for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
+       codecs = audio_codecs = 0;
+       for (c = 0; c < AZX_MAX_CODECS; c++) {
                if ((chip->codec_mask & (1 << c)) & probe_mask) {
-                       err = snd_hda_codec_new(chip->bus, c, NULL);
+                       struct hda_codec *codec;
+                       err = snd_hda_codec_new(chip->bus, c, &codec);
                        if (err < 0)
                                continue;
                        codecs++;
+                       if (codec->afg)
+                               audio_codecs++;
                }
        }
-       if (! codecs) {
+       if (!audio_codecs) {
+               /* probe additional slots if no codec is found */
+               for (; c < azx_max_codecs[chip->driver_type]; c++) {
+                       if ((chip->codec_mask & (1 << c)) & probe_mask) {
+                               err = snd_hda_codec_new(chip->bus, c, NULL);
+                               if (err < 0)
+                                       continue;
+                               codecs++;
+                       }
+               }
+       }
+       if (!codecs) {
                snd_printk(KERN_ERR SFX "no codecs initialized\n");
                return -ENXIO;
        }
@@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device)
 /*
  * white/black-listing for position_fix
  */
-static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
+static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
        {}
 };
@@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = {
        { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
        { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
        { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
+       { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
+       { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */
        { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
        { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
        { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
index 39718d6cdadd381435a149ecc6eb0ff62e28c8fc..be12b8814c39b62d8e27ee65b0f9fce0c49aedb6 100644 (file)
@@ -148,6 +148,11 @@ struct hda_multi_out {
 
 int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
 int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+                                 struct hda_multi_out *mout,
+                                 unsigned int stream_tag,
+                                 unsigned int format,
+                                 struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
                                  struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
@@ -217,6 +222,12 @@ enum {
        AUTO_PIN_LAST
 };
 
+enum {
+       AUTO_PIN_LINE_OUT,
+       AUTO_PIN_SPEAKER_OUT,
+       AUTO_PIN_HP_OUT
+};
+
 extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
 
 struct auto_pin_cfg {
@@ -225,6 +236,7 @@ struct auto_pin_cfg {
        int speaker_outs;
        hda_nid_t speaker_pins[5];
        int hp_outs;
+       int line_out_type;      /* AUTO_PIN_XXX_OUT */
        hda_nid_t hp_pins[5];
        hda_nid_t input_pins[AUTO_PIN_LAST];
        hda_nid_t dig_out_pin;
index f94f1f22889ee07ca48f7cc0557c9245e5dd860c..0e1a879663fa548b2ce8fde95f20c86ecb795262 100644 (file)
@@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                          struct hda_codec *codec,
+                                          unsigned int stream_tag,
+                                          unsigned int format,
+                                          struct snd_pcm_substream *substream)
+{
+       struct ad198x_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+                                            format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
        .nid = 0, /* fill later */
        .ops = {
                .open = ad198x_dig_playback_pcm_open,
-               .close = ad198x_dig_playback_pcm_close
+               .close = ad198x_dig_playback_pcm_close,
+               .prepare = ad198x_dig_playback_pcm_prepare
        },
 };
 
@@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = {
        { } /* end */
 };
 
-/* additional verbs for 3-stack model */
-static struct hda_verb ad1986a_3st_init_verbs[] = {
-       /* Mic and line-in selectors */
-       {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
-       {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
-       { } /* end */
-};
-
 static struct hda_verb ad1986a_ch2_init[] = {
        /* Surround out -> Line In */
-       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+       /* Line-in selectors */
+       { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
        /* CLFE -> Mic in */
-       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+       /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
+       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
        { } /* end */
 };
 
 static struct hda_verb ad1986a_ch4_init[] = {
        /* Surround out -> Surround */
-       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
        /* CLFE -> Mic in */
-       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-       { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
        { } /* end */
 };
 
 static struct hda_verb ad1986a_ch6_init[] = {
        /* Surround out -> Surround out */
-       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+       { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
        /* CLFE -> CLFE */
-       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-       { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+       { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
        { } /* end */
 };
 
@@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
+       SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
        SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
        SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
@@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec)
        case AD1986A_3STACK:
                spec->num_mixers = 2;
                spec->mixers[1] = ad1986a_3st_mixers;
-               spec->num_init_verbs = 3;
-               spec->init_verbs[1] = ad1986a_3st_init_verbs;
-               spec->init_verbs[2] = ad1986a_ch2_init;
+               spec->num_init_verbs = 2;
+               spec->init_verbs[1] = ad1986a_ch2_init;
                spec->channel_mode = ad1986a_modes;
                spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
                spec->need_dac_fix = 1;
@@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
 
        sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
        if (sel > 0) {
-               sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
-               if (sel <= 3)
+               sel = snd_hda_codec_read(codec, 0x0b, 0,
+                                        AC_VERB_GET_CONNECT_SEL, 0);
+               if (sel < 3)
                        sel++;
                else
                        sel = 0;
@@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
                                            struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       unsigned int sel;
+       unsigned int val, sel;
        int change;
 
+       val = ucontrol->value.enumerated.item[0];
        sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
-       if (! ucontrol->value.enumerated.item[0]) {
+       if (!val) {
                change = sel != 0;
-               if (change)
-                       snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
+               if (change || codec->in_resume)
+                       snd_hda_codec_write(codec, 0x02, 0,
+                                           AC_VERB_SET_CONNECT_SEL, 0);
        } else {
                change = sel == 0;
-               if (change)
-                       snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
-               sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
-               change |= sel == ucontrol->value.enumerated.item[0];
-               if (change)
-                       snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
-                                           ucontrol->value.enumerated.item[0] - 1);
+               if (change || codec->in_resume)
+                       snd_hda_codec_write(codec, 0x02, 0,
+                                           AC_VERB_SET_CONNECT_SEL, 1);
+               sel = snd_hda_codec_read(codec, 0x0b, 0,
+                                        AC_VERB_GET_CONNECT_SEL, 0) + 1;
+               change |= sel != val;
+               if (change || codec->in_resume)
+                       snd_hda_codec_write(codec, 0x0b, 0,
+                                           AC_VERB_SET_CONNECT_SEL, val - 1);
        }
        return change;
 }
index 831469d3a923db7dd64bd857b287d8379ba4b1ed..f8eb4c90f801a677700a62b048ffd82c85efcaa7 100644 (file)
@@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                           struct hda_codec *codec,
+                                           unsigned int stream_tag,
+                                           unsigned int format,
+                                           struct snd_pcm_substream *substream)
+{
+       struct atihdmi_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+                                            format, substream);
+}
+
 static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
        .substreams = 1,
        .channels_min = 2,
@@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
        .nid = 0x2, /* NID to query formats and rates and setup streams */
        .ops = {
                .open = atihdmi_dig_playback_pcm_open,
-               .close = atihdmi_dig_playback_pcm_close
+               .close = atihdmi_dig_playback_pcm_close,
+               .prepare = atihdmi_dig_playback_pcm_prepare
        },
 };
 
@@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec)
  */
 struct hda_codec_preset snd_hda_preset_atihdmi[] = {
        { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
-       { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
+       { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
+       { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi },
        {} /* terminator */
 };
index 5b9d3a31a1ae8f261c527985abe363f57b86f4d4..3c722e667bc8cf4d4686d571f7953017c72474c6 100644 (file)
@@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                           struct hda_codec *codec,
+                                           unsigned int stream_tag,
+                                           unsigned int format,
+                                           struct snd_pcm_substream *substream)
+{
+       struct cmi_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+                                            format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
        /* NID is set in cmi9880_build_pcms */
        .ops = {
                .open = cmi9880_dig_playback_pcm_open,
-               .close = cmi9880_dig_playback_pcm_close
+               .close = cmi9880_dig_playback_pcm_close,
+               .prepare = cmi9880_dig_playback_pcm_prepare
        },
 };
 
index 46e93c6b9a425cb543367dd34f7e94d2f43a3f27..a5a4b2bddf200a8daecde2b76c28b24f702a6231 100644 (file)
@@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                        struct hda_codec *codec,
+                                        unsigned int stream_tag,
+                                        unsigned int format,
+                                        struct snd_pcm_substream *substream)
+{
+       struct conexant_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+                                            stream_tag,
+                                            format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
        .nid = 0, /* fill later */
        .ops = {
                .open = conexant_dig_playback_pcm_open,
-               .close = conexant_dig_playback_pcm_close
+               .close = conexant_dig_playback_pcm_close,
+               .prepare = conexant_dig_playback_pcm_prepare
        },
 };
 
@@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
          .put = conexant_ch_mode_put, \
          .private_value = nid | (dir<<16) }
 
-static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}                                
-
-static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int val = snd_hda_codec_read(codec, nid, 0,
-                                             AC_VERB_GET_GPIO_DATA, 0x00);
-
-       *valp = (val & mask) != 0;
-       return 0;
-}
-
-static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
-                            struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
-                                                   AC_VERB_GET_GPIO_DATA,
-                                                   0x00);
-       unsigned int old_data = gpio_data;
-
-       /* Set/unset the masked GPIO bit(s) as needed */
-       if (val == 0)
-               gpio_data &= ~mask;
-       else
-               gpio_data |= mask;
-       if (gpio_data == old_data && !codec->in_resume)
-               return 0;
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
-       return 1;
-}
-
-#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .info = cxt_gpio_data_info, \
-         .get = cxt_gpio_data_get, \
-         .put = cxt_gpio_data_put, \
-         .private_value = nid | (mask<<16) }
-#if 0
-static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
-                              struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}                                
-
-static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long *valp = ucontrol->value.integer.value;
-       unsigned int val = snd_hda_codec_read(codec, nid, 0,
-                                             AC_VERB_GET_DIGI_CONVERT, 0x00);
-
-       *valp = (val & mask) != 0;
-       return 0;
-}
-
-static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
-                             struct snd_ctl_elem_value *ucontrol)
-{
-       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-       hda_nid_t nid = kcontrol->private_value & 0xffff;
-       unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-       long val = *ucontrol->value.integer.value;
-       unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-                                                   AC_VERB_GET_DIGI_CONVERT,
-                                                   0x00);
-       unsigned int old_data = ctrl_data;
-
-       /* Set/unset the masked control bit(s) as needed */
-       if (val == 0)
-               ctrl_data &= ~mask;
-       else
-               ctrl_data |= mask;
-       if (ctrl_data == old_data && !codec->in_resume)
-               return 0;
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-                           ctrl_data);
-       return 1;
-}
-
-#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
-       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-         .info = cxt_spdif_ctrl_info, \
-         .get = cxt_spdif_ctrl_get, \
-         .put = cxt_spdif_ctrl_put, \
-         .private_value = nid | (mask<<16) }
-#endif
 #endif /* CONFIG_SND_DEBUG */
 
 /* Conexant 5045 specific */
@@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
        bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
        snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
        snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
+
        bits = spec->cur_eapd ? 0 : 0x80;
        snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
        snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
@@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
+/* toggle input of built-in and mic jack appropriately */
+static void cxt5045_hp_automic(struct hda_codec *codec)
+{
+       static struct hda_verb mic_jack_on[] = {
+               {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+               {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+               {}
+       };
+       static struct hda_verb mic_jack_off[] = {
+               {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+               {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+               {}
+       };
+       unsigned int present;
+
+       present = snd_hda_codec_read(codec, 0x12, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       if (present)
+               snd_hda_sequence_write(codec, mic_jack_on);
+       else
+               snd_hda_sequence_write(codec, mic_jack_off);
+}
+
 
 /* mute internal speaker if HP is plugged */
 static void cxt5045_hp_automute(struct hda_codec *codec)
@@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
        spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 
-       bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
+       bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; 
        snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
        snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
 }
@@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
        case CONEXANT_HP_EVENT:
                cxt5045_hp_automute(codec);
                break;
+       case CONEXANT_MIC_EVENT:
+               cxt5045_hp_automic(codec);
+               break;
+
        }
 }
 
@@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
                .get = conexant_mux_enum_get,
                .put = conexant_mux_enum_put
        },
-       HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
+       HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
+       HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Volume",
@@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
 static struct hda_verb cxt5045_init_verbs[] = {
        /* Line in, Mic */
        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
        /* HP, Amp  */
        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
        {0x17, AC_VERB_SET_CONNECT_SEL,0x01},
@@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = {
        {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
         AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
        /* Record selector: Int mic */
-       {0x1a, AC_VERB_SET_CONNECT_SEL,0x0},
+       {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
        /* SPDIF route: PCM */
        { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
-       /* pin sensing on HP and Mic jacks */
-       {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
        /* EAPD */
        {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
        { } /* end */
 };
 
+
+static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
+       /* pin sensing on HP jack */
+       {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
+       { } /* end */
+};
+
+static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
+       /* pin sensing on HP jack */
+       {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
+       { } /* end */
+};
+
 #ifdef CONFIG_SND_DEBUG
 /* Test configuration for debugging, modelled after the ALC260 test
  * configuration.
@@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
        /* Output controls */
        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
        HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
        
        /* Modes for retasking pin widgets */
        CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
@@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
        CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
 
        /* Loopback mixer controls */
-       HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT),
-       HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT),
-       HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT),
-       HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT),
-       HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT),
-       HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT),
-       HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT),
-
-       HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT),
-       HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT),
-       HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT),
+
+       HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
+       HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Input Source",
@@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
                .get = conexant_mux_enum_get,
                .put = conexant_mux_enum_put,
        },
-
        { } /* end */
 };
 
 static struct hda_verb cxt5045_test_init_verbs[] = {
+       /* Set connections */
+       { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
+       { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
+       { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
        /* Enable retasking pins as output, initially without power amp */
        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 
        /* Disable digital (SPDIF) pins initially, but users can enable
         * them via a mixer switch.  In the case of SPDIF-out, this initverb
@@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = {
         * pin)
         */
        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
 
        /* Mute all inputs to mixer widget (even unconnected ones) */
        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
@@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec)
 
 
 enum {
-       CXT5045_LAPTOP, /* Laptops w/ EAPD support */
+       CXT5045_LAPTOP,  /* Laptops w/ EAPD support */
+       CXT5045_FUJITSU, /* Laptops w/ EAPD support */ 
 #ifdef CONFIG_SND_DEBUG
        CXT5045_TEST,
 #endif
@@ -836,6 +778,7 @@ enum {
 
 static const char *cxt5045_models[CXT5045_MODELS] = {
        [CXT5045_LAPTOP]        = "laptop",
+       [CXT5045_FUJITSU]       = "fujitsu",
 #ifdef CONFIG_SND_DEBUG
        [CXT5045_TEST]          = "test",
 #endif
@@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
 static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP),
        SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP),
-       SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP),
+       SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP),
+       SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP),
+       SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP),
+       SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU),
+       SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP),
        {}
 };
 
@@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec)
 
 
        codec->patch_ops = conexant_patch_ops;
-       codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
 
        board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
                                                  cxt5045_models,
                                                  cxt5045_cfg_tbl);
        switch (board_config) {
        case CXT5045_LAPTOP:
+               codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
+               spec->input_mux = &cxt5045_capture_source;
+               spec->num_init_verbs = 2;
+               spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
+               spec->mixers[0] = cxt5045_mixers;
+               codec->patch_ops.init = cxt5045_init;
+               break;
+       case CXT5045_FUJITSU:
                spec->input_mux = &cxt5045_capture_source;
                spec->num_init_verbs = 2;
-               spec->init_verbs[1] = cxt5045_init_verbs;
+               spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
                spec->mixers[0] = cxt5045_mixers;
                codec->patch_ops.init = cxt5045_init;
                break;
@@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = {
 };
 
 static struct hda_input_mux cxt5047_capture_source = {
-       .num_items = 2,
+       .num_items = 1,
        .items = {
-               { "ExtMic", 0x0 },
-               { "IntMic", 0x1 },
+               { "Mic", 0x2 },
        }
 };
 
@@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec)
        };
        unsigned int present;
 
-       present = snd_hda_codec_read(codec, 0x08, 0,
+       present = snd_hda_codec_read(codec, 0x15, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
        if (present)
                snd_hda_sequence_write(codec, mic_jack_on);
@@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
 }
 
 static struct snd_kcontrol_new cxt5047_mixers[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Capture Source",
-               .info = conexant_mux_enum_info,
-               .get = conexant_mux_enum_get,
-               .put = conexant_mux_enum_put
-       },
        HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT),
        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
        HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
        HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
        HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
        HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Volume",
-               .info = snd_hda_mixer_amp_volume_info,
-               .get = snd_hda_mixer_amp_volume_get,
-               .put = cxt5047_hp_master_vol_put,
-               .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
-       },
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Master Playback Switch",
-               .info = cxt_eapd_info,
-               .get = cxt_eapd_get,
-               .put = cxt5047_hp_master_sw_put,
-               .private_value = 0x13,
-       },
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT),
 
        {}
 };
@@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = {
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
-       /* HP, Amp, Speaker  */
-       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-       {0x1A, AC_VERB_SET_CONNECT_SEL,0x00},
-       {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
-       {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
-        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
+       /* HP, Speaker  */
+       {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+       {0x13, AC_VERB_SET_CONNECT_SEL,0x1},
        {0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
-       /* Record selector: Front mic */
+       /* Record selector: Mic */
        {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
+       {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
+       {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
+       {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+        AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
        /* SPDIF route: PCM */
        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
        /* Enable unsolicited events */
@@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
        /* Speaker routing */
        {0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
-       /* Change default to ExtMic for recording */
-       {0x1a, AC_VERB_SET_CONNECT_SEL,0x2},
        {}
 };
 
@@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = {
        {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
        /* Record selector: Ext Mic */
        {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
-       {0x1a, AC_VERB_SET_CONNECT_SEL,0x02},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
        /* Speaker routing */
@@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
                .get = conexant_mux_enum_get,
                .put = conexant_mux_enum_put,
        },
-       /* Controls for GPIO pins, assuming they exist and are configured
-       * as outputs
-       */
-       CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
-       CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
-       CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
-       CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
        { } /* end */
 };
 
index fba3cb11bc2a46da818a6662f9be630c38e8167b..a4ede27af021bd01d8e6ea2bca14fbcb724ff267 100644 (file)
@@ -74,6 +74,8 @@ enum {
        ALC260_HP_3013,
        ALC260_FUJITSU_S702X,
        ALC260_ACER,
+       ALC260_WILL,
+       ALC260_REPLACER_672V,
 #ifdef CONFIG_SND_DEBUG
        ALC260_TEST,
 #endif
@@ -115,15 +117,28 @@ enum {
        ALC861VD_3ST,
        ALC861VD_3ST_DIG,
        ALC861VD_6ST_DIG,
+       ALC861VD_LENOVO,
        ALC861VD_AUTO,
        ALC861VD_MODEL_LAST,
 };
 
+/* ALC662 models */
+enum {
+       ALC662_3ST_2ch_DIG,
+       ALC662_3ST_6ch_DIG,
+       ALC662_3ST_6ch,
+       ALC662_5ST_DIG,
+       ALC662_LENOVO_101E,
+       ALC662_AUTO,
+       ALC662_MODEL_LAST,
+};
+
 /* ALC882 models */
 enum {
        ALC882_3ST_DIG,
        ALC882_6ST_DIG,
        ALC882_ARIMA,
+       ALC882_W2JC,
        ALC882_AUTO,
        ALC885_MACPRO,
        ALC882_MODEL_LAST,
@@ -141,6 +156,7 @@ enum {
        ALC883_ACER,
        ALC883_MEDION,
        ALC883_LAPTOP_EAPD,
+       ALC883_LENOVO_101E_2ch,
        ALC883_AUTO,
        ALC883_MODEL_LAST,
 };
@@ -163,7 +179,7 @@ struct alc_spec {
        struct hda_pcm_stream *stream_analog_playback;
        struct hda_pcm_stream *stream_analog_capture;
 
-       char *stream_name_digital;      /* digital PCM stream */ 
+       char *stream_name_digital;      /* digital PCM stream */
        struct hda_pcm_stream *stream_digital_playback;
        struct hda_pcm_stream *stream_digital_capture;
 
@@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
                                                 0x00);
 
-       if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 
+       if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
                val = alc_pin_mode_min(dir);
 
        change = pinctl != alc_pin_mode_values[val];
@@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
        uinfo->value.integer.min = 0;
        uinfo->value.integer.max = 1;
        return 0;
-}                                
+}
+
 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
                             struct snd_ctl_elem_value *ucontrol)
 {
@@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
        uinfo->value.integer.min = 0;
        uinfo->value.integer.max = 1;
        return 0;
-}                                
+}
+
 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
 {
@@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec,
        spec->multiout.hp_nid = preset->hp_nid;
        
        spec->num_mux_defs = preset->num_mux_defs;
-       if (! spec->num_mux_defs)
+       if (!spec->num_mux_defs)
                spec->num_mux_defs = 1;
        spec->input_mux = preset->input_mux;
 
@@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec,
        spec->init_hook = preset->init_hook;
 }
 
+/* Enable GPIO mask and set output */
+static struct hda_verb alc_gpio1_init_verbs[] = {
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+       { }
+};
+
+static struct hda_verb alc_gpio2_init_verbs[] = {
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
+       { }
+};
+
+static struct hda_verb alc_gpio3_init_verbs[] = {
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+       { }
+};
+
+/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
+ *     31 ~ 16 :       Manufacture ID
+ *     15 ~ 8  :       SKU ID
+ *     7  ~ 0  :       Assembly ID
+ *     port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
+ */
+static void alc_subsystem_id(struct hda_codec *codec,
+                            unsigned int porta, unsigned int porte,
+                            unsigned int portd)
+{
+       unsigned int ass, tmp;
+
+       ass = codec->subsystem_id;
+       if (!(ass & 1))
+               return;
+
+       /* Override */
+       tmp = (ass & 0x38) >> 3;        /* external Amp control */
+       switch (tmp) {
+       case 1:
+               snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
+               break;
+       case 3:
+               snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
+               break;
+       case 7:
+               snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
+               break;
+       case 5:
+               switch (codec->vendor_id) {
+               case 0x10ec0862:
+               case 0x10ec0660:
+               case 0x10ec0662:        
+               case 0x10ec0267:
+               case 0x10ec0268:
+                       snd_hda_codec_write(codec, 0x14, 0,
+                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       snd_hda_codec_write(codec, 0x15, 0,
+                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       return;
+               }
+       case 6:
+               if (ass & 4) {  /* bit 2 : 0 = Desktop, 1 = Laptop */
+                       hda_nid_t port = 0;
+                       tmp = (ass & 0x1800) >> 11;
+                       switch (tmp) {
+                       case 0: port = porta; break;
+                       case 1: port = porte; break;
+                       case 2: port = portd; break;
+                       }
+                       if (port)
+                               snd_hda_codec_write(codec, port, 0,
+                                                   AC_VERB_SET_EAPD_BTLENABLE,
+                                                   2);
+               }
+               snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+               snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
+                                   (tmp == 5 ? 0x3040 : 0x3050));
+               break;
+       }
+}
+
 /*
  * ALC880 3-stack model
  *
@@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {
 static hda_nid_t alc880_6st_dac_nids[4] = {
        /* front, rear, clfe, rear_surr */
        0x02, 0x03, 0x04, 0x05
-};     
+};
 
 static struct hda_input_mux alc880_6stack_capture_source = {
        .num_items = 4,
@@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = {
 };
 
 /* toggle speaker-output according to the hp-jack state */
-static void alc880_uniwill_automute(struct hda_codec *codec)
+static void alc880_uniwill_hp_automute(struct hda_codec *codec)
 {
        unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x14, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
        snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
+}
+
+/* auto-toggle front mic */
+static void alc880_uniwill_mic_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x18, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-       snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-                           0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+                                0x80, bits);
+}
+
+static void alc880_uniwill_automute(struct hda_codec *codec)
+{
+       alc880_uniwill_hp_automute(codec);
+       alc880_uniwill_mic_automute(codec);
 }
 
 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
        /* Looks like the unsol event is incompatible with the standard
         * definition.  4bit tag is placed at 28 bit!
         */
-       if ((res >> 28) == ALC880_HP_EVENT ||
-           (res >> 28) == ALC880_MIC_EVENT)
-               alc880_uniwill_automute(codec);
+       switch (res >> 28) {
+       case ALC880_HP_EVENT:
+               alc880_uniwill_hp_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc880_uniwill_mic_automute(codec);
+               break;
+       }
 }
 
 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
 {
        unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x14, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-
+       bits = present ? 0x80 : 0;
        snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
 }
 
 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
         */
        if ((res >> 28) == ALC880_HP_EVENT)
                alc880_uniwill_p53_hp_automute(codec);
-       if ((res >> 28) == ALC880_DCVOL_EVENT) 
+       if ((res >> 28) == ALC880_DCVOL_EVENT)
                alc880_uniwill_p53_dcvol_automute(codec);
 }
 
@@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
 };
 
 /* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio1_init_verbs[] = {
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-
-       { }
-};
-
-/* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio2_init_verbs[] = {
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
-
-       { }
-};
+#define alc880_gpio1_init_verbs        alc_gpio1_init_verbs
+#define alc880_gpio2_init_verbs        alc_gpio2_init_verbs
 
 /* Clevo m520g init */
 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
@@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = {
 static void alc880_lg_automute(struct hda_codec *codec)
 {
        unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x1b, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
        snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
 }
 
 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
 static void alc880_lg_lw_automute(struct hda_codec *codec)
 {
        unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x1b, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
        snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
 }
 
 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 }
 
+static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                          struct hda_codec *codec,
+                                          unsigned int stream_tag,
+                                          unsigned int format,
+                                          struct snd_pcm_substream *substream)
+{
+       struct alc_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+                                            stream_tag, format, substream);
+}
+
 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
                                         struct hda_codec *codec,
                                         struct snd_pcm_substream *substream)
@@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
        /* NID is set in alc_build_pcms */
        .ops = {
                .open = alc880_dig_playback_pcm_open,
-               .close = alc880_dig_playback_pcm_close
+               .close = alc880_dig_playback_pcm_close,
+               .prepare = alc880_dig_playback_pcm_prepare
        },
 };
 
@@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        unsigned int i;
 
-       if (! spec)
+       if (!spec)
                return;
 
        if (spec->kctl_alloc) {
@@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
 static struct alc_config_preset alc880_presets[] = {
        [ALC880_3ST] = {
                .mixers = { alc880_three_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_3stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
                .dac_nids = alc880_dac_nids,
                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
@@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_3ST_DIG] = {
                .mixers = { alc880_three_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_3stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
                .dac_nids = alc880_dac_nids,
                .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = {
                .input_mux = &alc880_capture_source,
        },
        [ALC880_5ST] = {
-               .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+               .mixers = { alc880_three_stack_mixer,
+                           alc880_five_stack_mixer},
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_5stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
                .dac_nids = alc880_dac_nids,
                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
@@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = {
                .input_mux = &alc880_capture_source,
        },
        [ALC880_5ST_DIG] = {
-               .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+               .mixers = { alc880_three_stack_mixer,
+                           alc880_five_stack_mixer },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_5stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
                .dac_nids = alc880_dac_nids,
                .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_6ST] = {
                .mixers = { alc880_six_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_6stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
                .dac_nids = alc880_6st_dac_nids,
                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
@@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_6ST_DIG] = {
                .mixers = { alc880_six_stack_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_6stack_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
                .dac_nids = alc880_6st_dac_nids,
                .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_W810] = {
                .mixers = { alc880_w810_base_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_w810_init_verbs,
                                alc880_gpio2_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
                .dac_nids = alc880_w810_dac_nids,
@@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_Z71V] = {
                .mixers = { alc880_z71v_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_z71v_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
                .dac_nids = alc880_z71v_dac_nids,
                .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_F1734] = {
                .mixers = { alc880_f1734_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_f1734_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
                .dac_nids = alc880_f1734_dac_nids,
                .hp_nid = 0x02,
@@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_ASUS] = {
                .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_asus_init_verbs,
                                alc880_gpio1_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
                .dac_nids = alc880_asus_dac_nids,
@@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_ASUS_DIG] = {
                .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_asus_init_verbs,
                                alc880_gpio1_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
                .dac_nids = alc880_asus_dac_nids,
@@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_ASUS_DIG2] = {
                .mixers = { alc880_asus_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_asus_init_verbs,
                                alc880_gpio2_init_verbs }, /* use GPIO2 */
                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
                .dac_nids = alc880_asus_dac_nids,
@@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = {
        },
        [ALC880_ASUS_W1V] = {
                .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
-               .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+               .init_verbs = { alc880_volume_init_verbs,
+                               alc880_pin_asus_init_verbs,
                                alc880_gpio1_init_verbs },
                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
                .dac_nids = alc880_asus_dac_nids,
@@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = {
                .init_hook = alc880_uniwill_p53_hp_automute,
        },
        [ALC880_FUJITSU] = {
-               .mixers = { alc880_fujitsu_mixer, 
+               .mixers = { alc880_fujitsu_mixer,
                            alc880_pcbeep_mixer, },
                .init_verbs = { alc880_volume_init_verbs,
                                alc880_uniwill_p53_init_verbs,
@@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = {
                .mixers = { alc880_lg_lw_mixer },
                .init_verbs = { alc880_volume_init_verbs,
                                alc880_lg_lw_init_verbs },
-               .num_dacs = 1, 
+               .num_dacs = 1,
                .dac_nids = alc880_dac_nids,
                .dig_out_nid = ALC880_DIGOUT_NID,
                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
@@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = {
 };
 
 /* add dynamic controls */
-static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
+static int add_control(struct alc_spec *spec, int type, const char *name,
+                      unsigned long val)
 {
        struct snd_kcontrol_new *knew;
 
        if (spec->num_kctl_used >= spec->num_kctl_alloc) {
                int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
 
-               knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
-               if (! knew)
+               /* array + terminator */
+               knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
+               if (!knew)
                        return -ENOMEM;
                if (spec->kctl_alloc) {
-                       memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+                       memcpy(knew, spec->kctl_alloc,
+                              sizeof(*knew) * spec->num_kctl_alloc);
                        kfree(spec->kctl_alloc);
                }
                spec->kctl_alloc = knew;
@@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
        knew = &spec->kctl_alloc[spec->num_kctl_used];
        *knew = alc880_control_templates[type];
        knew->name = kstrdup(name, GFP_KERNEL);
-       if (! knew->name)
+       if (!knew->name)
                return -ENOMEM;
        knew->private_value = val;
        spec->num_kctl_used++;
@@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
 #define ALC880_PIN_CD_NID              0x1c
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
+                                    const struct auto_pin_cfg *cfg)
 {
        hda_nid_t nid;
        int assigned[4];
@@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi
                        continue;
                /* search for an empty channel */
                for (j = 0; j < cfg->line_outs; j++) {
-                       if (! assigned[j]) {
-                               spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
+                       if (!assigned[j]) {
+                               spec->multiout.dac_nids[i] =
+                                       alc880_idx_to_dac(j);
                                assigned[j] = 1;
                                break;
                        }
@@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
                                             const struct auto_pin_cfg *cfg)
 {
        char name[32];
-       static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+       static const char *chname[4] = {
+               "Front", "Surround", NULL /*CLFE*/, "Side"
+       };
        hda_nid_t nid;
        int i, err;
 
        for (i = 0; i < cfg->line_outs; i++) {
-               if (! spec->multiout.dac_nids[i])
+               if (!spec->multiout.dac_nids[i])
                        continue;
                nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
                if (i == 2) {
                        /* Center/LFE */
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
-                                              HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "Center Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
-                                              HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "LFE Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "Center Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "LFE Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
                } else {
                        sprintf(name, "%s Playback Volume", chname[i]);
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                        sprintf(name, "%s Playback Switch", chname[i]);
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                              HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
                }
        }
@@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
        int err;
        char name[32];
 
-       if (! pin)
+       if (!pin)
                return 0;
 
        if (alc880_is_fixed_pin(pin)) {
                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
                /* specify the DAC as the extra output */
-               if (! spec->multiout.hp_nid)
+               if (!spec->multiout.hp_nid)
                        spec->multiout.hp_nid = nid;
                else
                        spec->multiout.extra_out_nid[0] = nid;
                /* control HP volume/switch on the output mixer amp */
                nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
                sprintf(name, "%s Playback Volume", pfx);
-               if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                                      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
                sprintf(name, "%s Playback Switch", pfx);
-               if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                      HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+               err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+               if (err < 0)
                        return err;
        } else if (alc880_is_multi_pin(pin)) {
                /* set manual connection */
                /* we have only a switch on HP-out PIN */
                sprintf(name, "%s Playback Switch", pfx);
-               if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                                      HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
        }
        return 0;
 }
 
 /* create input playback/capture controls for the given pin */
-static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
+static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
+                           const char *ctlname,
                            int idx, hda_nid_t mix_nid)
 {
        char name[32];
        int err;
 
        sprintf(name, "%s Playback Volume", ctlname);
-       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+       err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                         HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+       if (err < 0)
                return err;
        sprintf(name, "%s Playback Switch", ctlname);
-       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+       err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                         HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+       if (err < 0)
                return err;
        return 0;
 }
@@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
                                               idx, 0x0b);
                        if (err < 0)
                                return err;
-                       imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
-                       imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
+                       imux->items[imux->num_items].label =
+                               auto_pin_cfg_labels[i];
+                       imux->items[imux->num_items].index =
+                               alc880_input_pin_idx(cfg->input_pins[i]);
                        imux->num_items++;
                }
        }
@@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
                                              int dac_idx)
 {
        /* set as output */
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           pin_type);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           AMP_OUT_UNMUTE);
        /* need the manual connection? */
        if (alc880_is_multi_pin(nid)) {
                struct alc_spec *spec = codec->spec;
@@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
        }
 }
 
+static int get_pin_type(int line_out_type)
+{
+       if (line_out_type == AUTO_PIN_HP_OUT)
+               return PIN_HP;
+       else
+               return PIN_OUT;
+}
+
 static void alc880_auto_init_multi_out(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        int i;
-
+       
+       alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i < spec->autocfg.line_outs; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
-               alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
+               alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
        }
 }
 
@@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
                if (alc880_is_input_pin(nid)) {
-                       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                           i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           i <= AUTO_PIN_FRONT_MIC ?
+                                           PIN_VREF80 : PIN_IN);
                        if (nid != ALC880_PIN_CD_NID)
-                               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                               snd_hda_codec_write(codec, nid, 0,
+                                                   AC_VERB_SET_AMP_GAIN_MUTE,
                                                    AMP_OUT_MUTE);
                }
        }
 }
 
 /* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
 static int alc880_parse_auto_config(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        int err;
        static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
 
-       if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                               alc880_ignore)) < 0)
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc880_ignore);
+       if (err < 0)
                return err;
-       if (! spec->autocfg.line_outs)
+       if (!spec->autocfg.line_outs)
                return 0; /* can't find valid BIOS pin config */
 
-       if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-           (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-           (err = alc880_auto_create_extra_out(spec,
-                                               spec->autocfg.speaker_pins[0],
-                                               "Speaker")) < 0 ||
-           (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
-                                               "Headphone")) < 0 ||
-           (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+       err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc880_auto_create_extra_out(spec,
+                                          spec->autocfg.speaker_pins[0],
+                                          "Speaker");
+       if (err < 0)
+               return err;
+       err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+                                          "Headphone");
+       if (err < 0)
+               return err;
+       err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
 
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using 3-stack mode...\n");
@@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec)
        spec->stream_digital_playback = &alc880_pcm_digital_playback;
        spec->stream_digital_capture = &alc880_pcm_digital_capture;
 
-       if (! spec->adc_nids && spec->input_mux) {
+       if (!spec->adc_nids && spec->input_mux) {
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
-               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+               /* get type */
+               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
                if (wcap != AC_WID_AUD_IN) {
                        spec->adc_nids = alc880_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
-                       spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
+                       spec->mixers[spec->num_mixers] =
+                               alc880_capture_alt_mixer;
                        spec->num_mixers++;
                } else {
                        spec->adc_nids = alc880_adc_nids;
@@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {
        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
        { } /* end */
-};     
+};
 
 static struct snd_kcontrol_new alc260_input_mixer[] = {
        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
@@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
        { } /* end */
 };
 
+/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
+ * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
+ */
+static struct snd_kcontrol_new alc260_will_mixer[] = {
+       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+       ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+       ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+       { } /* end */
+};
+
+/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
+ * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
+ */
+static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
+       HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+       ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+       HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+       ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+       { } /* end */
+};
+
 /* capture mixer elements */
 static struct snd_kcontrol_new alc260_capture_mixer[] = {
        HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
@@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = {
        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        /* unmute LINE-2 out pin */
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+        * Line In 2 = 0x03
+        */
        /* mute CD */
        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
        /* mute Line In */
@@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = {
        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
        /* mute pin widget amp left and right (no gain on this amp) */
        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+        * Line In 2 = 0x03
+        */
        /* unmute CD */
        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
        /* unmute Line In */
@@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
        /* mute pin widget amp left and right (no gain on this amp) */
        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+       /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+        * Line In 2 = 0x03
+        */
        /* unmute CD */
        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
        /* unmute Line In */
@@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = {
        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 
-       /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
+       /* Unmute Line-out pin widget amp left and right
+        * (no equiv mixer ctrl)
+        */
        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = {
        { }
 };
 
+static struct hda_verb alc260_will_verbs[] = {
+       {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+       {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+       {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
+       {}
+};
+
+static struct hda_verb alc260_replacer_672v_verbs[] = {
+       {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+       {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+       {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
+
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+
+       {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc260_replacer_672v_automute(struct hda_codec *codec)
+{
+        unsigned int present;
+
+       /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
+        present = snd_hda_codec_read(codec, 0x0f, 0,
+                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       if (present) {
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
+               snd_hda_codec_write(codec, 0x0f, 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+       } else {
+               snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
+               snd_hda_codec_write(codec, 0x0f, 0,
+                                   AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+       }
+}
+
+static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
+                                       unsigned int res)
+{
+        if ((res >> 26) == ALC880_HP_EVENT)
+                alc260_replacer_672v_automute(codec);
+}
+
 /* Test configuration for debugging, modelled after the ALC880 test
  * configuration.
  */
@@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
                return 0; /* N/A */
        
        snprintf(name, sizeof(name), "%s Playback Volume", pfx);
-       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
+       err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
+       if (err < 0)
                return err;
        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
-       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
+       err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
+       if (err < 0)
                return err;
        return 1;
 }
@@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
                if (err < 0)
                        return err;
        }
-       return 0;       
+       return 0;
 }
 
 /* create playback/capture controls for input pins */
@@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
                if (cfg->input_pins[i] >= 0x12) {
                        idx = cfg->input_pins[i] - 0x12;
                        err = new_analog_input(spec, cfg->input_pins[i],
-                                              auto_pin_cfg_labels[i], idx, 0x07);
+                                              auto_pin_cfg_labels[i], idx,
+                                              0x07);
                        if (err < 0)
                                return err;
-                       imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+                       imux->items[imux->num_items].label =
+                               auto_pin_cfg_labels[i];
                        imux->items[imux->num_items].index = idx;
                        imux->num_items++;
                }
-               if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
+               if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
                        idx = cfg->input_pins[i] - 0x09;
                        err = new_analog_input(spec, cfg->input_pins[i],
-                                              auto_pin_cfg_labels[i], idx, 0x07);
+                                              auto_pin_cfg_labels[i], idx,
+                                              0x07);
                        if (err < 0)
                                return err;
-                       imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+                       imux->items[imux->num_items].label =
+                               auto_pin_cfg_labels[i];
                        imux->items[imux->num_items].index = idx;
                        imux->num_items++;
                }
@@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
                                              int sel_idx)
 {
        /* set as output */
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           pin_type);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           AMP_OUT_UNMUTE);
        /* need the manual connection? */
        if (nid >= 0x12) {
                int idx = nid - 0x12;
                snd_hda_codec_write(codec, idx + 0x0b, 0,
                                    AC_VERB_SET_CONNECT_SEL, sel_idx);
-                                   
        }
 }
 
@@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        hda_nid_t nid;
 
-       nid = spec->autocfg.line_out_pins[0];   
-       if (nid)
-               alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+       alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
+       nid = spec->autocfg.line_out_pins[0];
+       if (nid) {
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
+               alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
+       }
        
        nid = spec->autocfg.speaker_pins[0];
        if (nid)
@@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
 
        nid = spec->autocfg.hp_pins[0];
        if (nid)
-               alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
-}      
+               alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
+}
 
 #define ALC260_PIN_CD_NID              0x16
 static void alc260_auto_init_analog_input(struct hda_codec *codec)
@@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
                if (nid >= 0x12) {
-                       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                           i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           i <= AUTO_PIN_FRONT_MIC ?
+                                           PIN_VREF80 : PIN_IN);
                        if (nid != ALC260_PIN_CD_NID)
-                               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                               snd_hda_codec_write(codec, nid, 0,
+                                                   AC_VERB_SET_AMP_GAIN_MUTE,
                                                    AMP_OUT_MUTE);
                }
        }
@@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = {
        
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
        int err;
        static hda_nid_t alc260_ignore[] = { 0x17, 0 };
 
-       if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                               alc260_ignore)) < 0)
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc260_ignore);
+       if (err < 0)
                return err;
-       if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
+       err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
-       if (! spec->kctl_alloc)
+       if (!spec->kctl_alloc)
                return 0; /* can't find valid BIOS pin config */
-       if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+       err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
 
        spec->multiout.max_channels = 2;
@@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
        [ALC260_HP_3013]        = "hp-3013",
        [ALC260_FUJITSU_S702X]  = "fujitsu",
        [ALC260_ACER]           = "acer",
+       [ALC260_WILL]           = "will",
+       [ALC260_REPLACER_672V]  = "replacer",
 #ifdef CONFIG_SND_DEBUG
        [ALC260_TEST]           = "test",
 #endif
@@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
        SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
        SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
+       SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
+       SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
        {}
 };
 
@@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = {
                .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
                .input_mux = alc260_acer_capture_sources,
        },
+       [ALC260_WILL] = {
+               .mixers = { alc260_will_mixer,
+                           alc260_capture_mixer },
+               .init_verbs = { alc260_init_verbs, alc260_will_verbs },
+               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+               .dac_nids = alc260_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+               .adc_nids = alc260_adc_nids,
+               .dig_out_nid = ALC260_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc260_modes),
+               .channel_mode = alc260_modes,
+               .input_mux = &alc260_capture_source,
+       },
+       [ALC260_REPLACER_672V] = {
+               .mixers = { alc260_replacer_672v_mixer,
+                           alc260_capture_mixer },
+               .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
+               .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+               .dac_nids = alc260_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+               .adc_nids = alc260_adc_nids,
+               .dig_out_nid = ALC260_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc260_modes),
+               .channel_mode = alc260_modes,
+               .input_mux = &alc260_capture_source,
+               .unsol_event = alc260_replacer_672v_unsol_event,
+               .init_hook = alc260_replacer_672v_automute,
+       },
 #ifdef CONFIG_SND_DEBUG
        [ALC260_TEST] = {
                .mixers = { alc260_test_mixer,
@@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = {
 #define alc882_mux_enum_info alc_mux_enum_info
 #define alc882_mux_enum_get alc_mux_enum_get
 
-static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        struct alc_spec *spec = codec->spec;
@@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && ! codec->in_resume)
+       if (*cur_val == idx && !codec->in_resume)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
                unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       { } /* end */
+};
+
 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = {
        /* change to EAPD mode */
        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
        {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
-       { } 
+       { }
 };
 
 /* Mac Pro test */
@@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
 
        { }
 };
+
 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
 {
        unsigned int gpiostate, gpiomask, gpiodir;
@@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = {
 
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
        [ALC882_3ST_DIG]        = "3stack-dig",
        [ALC882_6ST_DIG]        = "6stack-dig",
        [ALC882_ARIMA]          = "arima",
+       [ALC882_W2JC]           = "w2jc",
        [ALC885_MACPRO]         = "macpro",
        [ALC882_AUTO]           = "auto",
 };
@@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
+       SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
        {}
 };
 
@@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = {
                .channel_mode = alc882_sixstack_modes,
                .input_mux = &alc882_capture_source,
        },
+       [ALC882_W2JC] = {
+               .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
+               .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
+                               alc880_gpio1_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+               .dac_nids = alc882_dac_nids,
+               .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+               .channel_mode = alc880_threestack_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc882_capture_source,
+               .dig_out_nid = ALC882_DIGOUT_NID,
+       },
        [ALC885_MACPRO] = {
                .mixers = { alc882_macpro_mixer },
                .init_verbs = { alc882_macpro_init_verbs },
@@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
 {
        /* set as output */
        struct alc_spec *spec = codec->spec;
-       int idx; 
-       
+       int idx;
+
        if (spec->multiout.dac_nids[dac_idx] == 0x25)
                idx = 4;
        else
                idx = spec->multiout.dac_nids[dac_idx] - 2;
 
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           pin_type);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           AMP_OUT_UNMUTE);
        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
 
 }
@@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int i;
 
+       alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i <= HDA_SIDE; i++) {
-               hda_nid_t nid = spec->autocfg.line_out_pins[i]; 
+               hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
-                       alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+                       alc882_auto_set_output_and_unmute(codec, nid, pin_type,
+                                                         i);
        }
 }
 
@@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
 
        pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
-               alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
+               /* use dac 0 */
+               alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 }
 
 #define alc882_is_input_pin(nid)       alc880_is_input_pin(nid)
@@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
                if (alc882_is_input_pin(nid)) {
-                       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                           i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           i <= AUTO_PIN_FRONT_MIC ?
+                                           PIN_VREF80 : PIN_IN);
                        if (nid != ALC882_PIN_CD_NID)
-                               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                               snd_hda_codec_write(codec, nid, 0,
+                                                   AC_VERB_SET_AMP_GAIN_MUTE,
                                                    AMP_OUT_MUTE);
                }
        }
@@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec)
        spec->stream_digital_playback = &alc882_pcm_digital_playback;
        spec->stream_digital_capture = &alc882_pcm_digital_capture;
 
-       if (! spec->adc_nids && spec->input_mux) {
+       if (!spec->adc_nids && spec->input_mux) {
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, 0x07);
-               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+               /* get type */
+               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
                if (wcap != AC_WID_AUD_IN) {
                        spec->adc_nids = alc882_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
-                       spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
+                       spec->mixers[spec->num_mixers] =
+                               alc882_capture_alt_mixer;
                        spec->num_mixers++;
                } else {
                        spec->adc_nids = alc882_adc_nids;
@@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = {
        /* ADC1-2 */
        0x08, 0x09,
 };
+
 /* input MUX */
 /* FIXME: should be a matrix-type input source selection */
 
@@ -5045,7 +5432,16 @@ static struct hda_input_mux alc883_capture_source = {
                { "CD", 0x4 },
        },
 };
-#define alc883_mux_enum_info alc_mux_enum_info
+
+static struct hda_input_mux alc883_lenovo_101e_capture_source = {
+       .num_items = 2,
+       .items = {
+               { "Mic", 0x1 },
+               { "Line", 0x2 },
+       },
+};
+
+#define alc883_mux_enum_info alc_mux_enum_info
 #define alc883_mux_enum_get alc_mux_enum_get
 
 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
@@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && ! codec->in_resume)
+       if (*cur_val == idx && !codec->in_resume)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
                unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
        *cur_val = idx;
        return 1;
 }
+
 /*
  * 2ch mode
  */
@@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
                .put = alc883_mux_enum_put,
        },
        { } /* end */
-};     
+};
 
 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
                .put = alc883_mux_enum_put,
        },
        { } /* end */
-};     
+};
+
+static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc883_mux_enum_info,
+               .get = alc883_mux_enum_get,
+               .put = alc883_mux_enum_put,
+       },
+       { } /* end */
+};
 
 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
        {
@@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 
        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-       {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 
-       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 
-       {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 
+       {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+       {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+
+       { } /* end */
+};
 
+static struct hda_verb alc883_lenovo_101e_verbs[] = {
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
+        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
        { } /* end */
 };
 
@@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
 static void alc883_tagra_automute(struct hda_codec *codec)
 {
        unsigned int present;
+       unsigned char bits;
 
        present = snd_hda_codec_read(codec, 0x14, 0,
                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
        snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
+                                0x80, bits);
        snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
-                                0x80, present ? 0x80 : 0);
-       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+                                0x80, bits);
+       snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+                           present ? 1 : 3);
 }
 
 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
                alc883_tagra_automute(codec);
 }
 
+static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x1b, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc883_lenovo_101e_all_automute(codec);
+       if ((res >> 26) == ALC880_FRONT_EVENT)
+               alc883_lenovo_101e_ispeaker_automute(codec);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = {
 
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = {
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+       /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
        /* Input mixer2 */
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+       /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 
        { }
@@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
        [ALC883_ACER]           = "acer",
        [ALC883_MEDION]         = "medion",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
+       [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
        [ALC883_AUTO]           = "auto",
 };
 
@@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
        SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
@@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+       SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
        {}
 };
 
@@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_3ST_6ch_modes,
                .need_dac_fix = 1,
                .input_mux = &alc883_capture_source,
-       },      
+       },
        [ALC883_3ST_6ch] = {
                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
                .init_verbs = { alc883_init_verbs },
@@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_3ST_6ch_modes,
                .need_dac_fix = 1,
                .input_mux = &alc883_capture_source,
-       },      
+       },
        [ALC883_6ST_DIG] = {
                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
                .init_verbs = { alc883_init_verbs },
@@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = {
                .channel_mode = alc883_3ST_2ch_modes,
                .input_mux = &alc883_capture_source,
        },
+       [ALC883_LENOVO_101E_2ch] = {
+               .mixers = { alc883_lenovo_101e_2ch_mixer},
+               .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_lenovo_101e_capture_source,
+               .unsol_event = alc883_lenovo_101e_unsol_event,
+               .init_hook = alc883_lenovo_101e_all_automute,
+       },
 };
 
 
@@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
 {
        /* set as output */
        struct alc_spec *spec = codec->spec;
-       int idx; 
-       
+       int idx;
+
        if (spec->multiout.dac_nids[dac_idx] == 0x25)
                idx = 4;
        else
@@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int i;
 
+       alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i <= HDA_SIDE; i++) {
-               hda_nid_t nid = spec->autocfg.line_out_pins[i]; 
+               hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
-                       alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+                       alc883_auto_set_output_and_unmute(codec, nid, pin_type,
+                                                         i);
        }
 }
 
@@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
        else if (err > 0)
                /* hack - override the init verbs */
                spec->init_verbs[0] = alc883_auto_init_verbs;
-                spec->mixers[spec->num_mixers] = alc883_capture_mixer;
-               spec->num_mixers++;
+       spec->mixers[spec->num_mixers] = alc883_capture_mixer;
+       spec->num_mixers++;
        return err;
 }
 
@@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec)
        spec->stream_digital_playback = &alc883_pcm_digital_playback;
        spec->stream_digital_capture = &alc883_pcm_digital_capture;
 
-       if (! spec->adc_nids && spec->input_mux) {
+       if (!spec->adc_nids && spec->input_mux) {
                spec->adc_nids = alc883_adc_nids;
                spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
        }
@@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = {
 
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = {
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},      
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 
        { }
 };
@@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force)
        struct alc_spec *spec = codec->spec;
        unsigned int mute;
 
-       if (force || ! spec->sense_updated) {
+       if (force || !spec->sense_updated) {
                unsigned int present;
                /* need to execute and sync at first */
                snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force)
        struct alc_spec *spec = codec->spec;
        unsigned int mute;
 
-       if (force || ! spec->sense_updated) {
+       if (force || !spec->sense_updated) {
                unsigned int present;
                /* need to execute and sync at first */
                snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
        struct alc_spec *spec = codec->spec;
        unsigned int mute;
 
-       if (force || ! spec->sense_updated) {
+       if (force || !spec->sense_updated) {
                unsigned int present;
                /* need to execute and sync at first */
                snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = {
 };
 
 /* add playback controls from the parsed DAC table */
-static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
+                                            const struct auto_pin_cfg *cfg)
 {
        hda_nid_t nid;
        int err;
@@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
 
        nid = cfg->line_out_pins[0];
        if (nid) {
-               if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
-                                      HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                 "Front Playback Volume",
+                                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
-               if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
-                                      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                 "Front Playback Switch",
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
        }
 
        nid = cfg->speaker_pins[0];
        if (nid) {
                if (nid == 0x16) {
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
-                                              HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "Speaker Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                         "Speaker Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                } else {
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                         "Speaker Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                }
        }
@@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
        if (nid) {
                /* spec->multiout.hp_nid = 2; */
                if (nid == 0x16) {
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
-                                              HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "Headphone Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                         "Headphone Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                } else {
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                         "Headphone Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                }
        }
-       return 0;       
+       return 0;
 }
 
 /* identical with ALC880 */
-#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
+#define alc262_auto_create_analog_input_ctls \
+       alc880_auto_create_analog_input_ctls
 
 /*
  * generic initialization of ADC, input mixers and output mixers
@@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = {
 
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
 
        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
         * mixer widget
-        * Note: PASD motherboards uses the Line In 2 as the input for front panel
-        * mic (mic 2)
+        * Note: PASD motherboards uses the Line In 2 as the input for
+        * front panel mic (mic 2)
         */
        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
        int err;
        static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
 
-       if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                               alc262_ignore)) < 0)
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc262_ignore);
+       if (err < 0)
                return err;
-       if (! spec->autocfg.line_outs)
+       if (!spec->autocfg.line_outs)
                return 0; /* can't find valid BIOS pin config */
-       if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-           (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+       err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
 
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_capture_source,
-       },      
+       },
        [ALC262_HP_BPC_D7000_WF] = {
                .mixers = { alc262_HP_BPC_WildWest_mixer },
                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
@@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_capture_source,
-       },      
+       },
        [ALC262_HP_BPC_D7000_WL] = {
                .mixers = { alc262_HP_BPC_WildWest_mixer,
                            alc262_HP_BPC_WildWest_option_mixer },
@@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_HP_capture_source,
-       },      
+       },
        [ALC262_BENQ_ED8] = {
                .mixers = { alc262_base_mixer },
                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc262_modes),
                .channel_mode = alc262_modes,
                .input_mux = &alc262_capture_source,
-       },              
+       },
 };
 
 static int patch_alc262(struct hda_codec *codec)
@@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec)
 
        codec->spec = spec;
 #if 0
-       /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
+       /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
+        * under-run
+        */
        {
        int tmp;
        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
@@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec)
        spec->stream_digital_playback = &alc262_pcm_digital_playback;
        spec->stream_digital_capture = &alc262_pcm_digital_capture;
 
-       if (! spec->adc_nids && spec->input_mux) {
+       if (!spec->adc_nids && spec->input_mux) {
                /* check whether NID 0x07 is valid */
                unsigned int wcap = get_wcaps(codec, 0x07);
 
-               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+               /* get type */
+               wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
                if (wcap != AC_WID_AUD_IN) {
                        spec->adc_nids = alc262_adc_nids_alt;
                        spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
-                       spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
+                       spec->mixers[spec->num_mixers] =
+                               alc262_capture_alt_mixer;
                        spec->num_mixers++;
                } else {
                        spec->adc_nids = alc262_adc_nids;
@@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec)
 static struct hda_verb alc861_threestack_ch2_init[] = {
        /* set pin widget 1Ah (line in) for input */
        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+       /* set pin widget 18h (mic1/2) for input, for mic also enable
+        * the vref
+        */
        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 
        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
 static struct hda_verb alc861_asus_ch2_init[] = {
        /* set pin widget 1Ah (line in) for input */
        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-       /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+       /* set pin widget 18h (mic1/2) for input, for mic also enable
+        * the vref
+        */
        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 
        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
+
         /* Capture mixer control */
        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
+
        /* Capture mixer control */
        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
        },
 
        { } /* end */
-};     
+};
 
 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
         /* output mixer control */
@@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
+
        /* Capture mixer control */
        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
        },
        { } /* end */
-};                     
+};
 
 static struct snd_kcontrol_new alc861_asus_mixer[] = {
         /* output mixer control */
@@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
+
        /* Capture mixer control */
        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = {
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+       /* hp used DAC 3 (Front) */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 
        { }
@@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+       /* hp used DAC 3 (Front) */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
        { }
 };
@@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
        /* port-E for HP out (front panel) */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
+       /* this has to be set to VREF80 */
+       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
        /* route front PCM to HP */
        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
        /* port-F for mic-in (front panel) with vref */
@@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+       /* hp used DAC 3 (Front) */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
        { }
 };
@@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = {
        /*
         * Unmute ADC0 and set the default input to mic-in
         */
-       /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
+       /* port-A for surround (rear panel)
+        * according to codec#0 this is the HP jack
+        */
        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
        /* route front PCM to HP */
        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
        /* port-E for HP out (front panel) */
-       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
+       /* this has to be set to VREF80 */
+       { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
        /* route front PCM to HP */
        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
        /* port-F for mic-in (front panel) with vref */
@@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, /* Output 0~12 step */
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
+       /* hp used DAC 3 (Front) */
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
        { }
 };
@@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {
        /*
         * Unmute ADC0 and set the default input to mic-in
         */
-//     {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+       /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
        
        /* Unmute DAC0~3 & spdif out*/
@@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = {
 
        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
-       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},            
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},    
-       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},    
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
 
-       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  // set Mic 1
+       {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
 
        { }
 };
 
 static struct hda_verb alc861_toshiba_init_verbs[] = {
        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
-        
+
        { }
 };
 
@@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec)
 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
                                       unsigned int res)
 {
-       /* Looks like the unsol event is incompatible with the standard
-        * definition.  6bit tag is placed at 26 bit!
-        */
        if ((res >> 26) == ALC880_HP_EVENT)
                alc861_toshiba_automute(codec);
 }
@@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = {
 };
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
+                                    const struct auto_pin_cfg *cfg)
 {
        int i;
        hda_nid_t nid;
@@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
                                             const struct auto_pin_cfg *cfg)
 {
        char name[32];
-       static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+       static const char *chname[4] = {
+               "Front", "Surround", NULL /*CLFE*/, "Side"
+       };
        hda_nid_t nid;
        int i, idx, err;
 
        for (i = 0; i < cfg->line_outs; i++) {
                nid = spec->multiout.dac_nids[i];
-               if (! nid)
+               if (!nid)
                        continue;
                if (nid == 0x05) {
                        /* Center/LFE */
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "Center Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
-                                              HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "LFE Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                } else {
-                       for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
+                       for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
+                            idx++)
                                if (nid == alc861_dac_nids[idx])
                                        break;
                        sprintf(name, "%s Playback Switch", chname[idx]);
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                }
        }
@@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
        int err;
        hda_nid_t nid;
 
-       if (! pin)
+       if (!pin)
                return 0;
 
        if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
                nid = 0x03;
-               if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-                                      HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+                                 "Headphone Playback Switch",
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
                spec->multiout.hp_nid = nid;
        }
@@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
 }
 
 /* create playback/capture controls for input pins */
-static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
+                                               const struct auto_pin_cfg *cfg)
 {
        struct hda_input_mux *imux = &spec->private_imux;
        int i, err, idx, idx1;
 
        for (i = 0; i < AUTO_PIN_LAST; i++) {
-               switch(cfg->input_pins[i]) {
+               switch (cfg->input_pins[i]) {
                case 0x0c:
                        idx1 = 1;
-                       idx = 2;        // Line In
+                       idx = 2;        /* Line In */
                        break;
                case 0x0f:
                        idx1 = 2;
-                       idx = 2;        // Line In
+                       idx = 2;        /* Line In */
                        break;
                case 0x0d:
                        idx1 = 0;
-                       idx = 1;        // Mic In 
+                       idx = 1;        /* Mic In */
                        break;
-               case 0x10:      
+               case 0x10:
                        idx1 = 3;
-                       idx = 1;        // Mic In 
+                       idx = 1;        /* Mic In */
                        break;
                case 0x11:
                        idx1 = 4;
-                       idx = 0;        // CD
+                       idx = 0;        /* CD */
                        break;
                default:
                        continue;
@@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str
 
                imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
                imux->items[imux->num_items].index = idx1;
-               imux->num_items++;      
+               imux->num_items++;
        }
        return 0;
 }
@@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = {
        { } /* end */
 };
 
-static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
+static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
+                                             hda_nid_t nid,
                                              int pin_type, int dac_idx)
 {
        /* set as output */
 
-       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-       snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+                           pin_type);
+       snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                           AMP_OUT_UNMUTE);
 
 }
 
@@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int i;
 
+       alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
        for (i = 0; i < spec->autocfg.line_outs; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
-                       alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
+                       alc861_auto_set_output_and_unmute(codec, nid, pin_type,
+                                                         spec->multiout.dac_nids[i]);
        }
 }
 
@@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
 
        pin = spec->autocfg.hp_pins[0];
        if (pin) /* connect to front */
-               alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
+               alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
+                                                 spec->multiout.dac_nids[0]);
 }
 
 static void alc861_auto_init_analog_input(struct hda_codec *codec)
@@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec)
 
        for (i = 0; i < AUTO_PIN_LAST; i++) {
                hda_nid_t nid = spec->autocfg.input_pins[i];
-               if ((nid>=0x0c) && (nid <=0x11)) {
-                       snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                           i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+               if (nid >= 0x0c && nid <= 0x11) {
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           i <= AUTO_PIN_FRONT_MIC ?
+                                           PIN_VREF80 : PIN_IN);
                }
        }
 }
 
 /* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
 static int alc861_parse_auto_config(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        int err;
        static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
 
-       if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                               alc861_ignore)) < 0)
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc861_ignore);
+       if (err < 0)
                return err;
-       if (! spec->autocfg.line_outs)
+       if (!spec->autocfg.line_outs)
                return 0; /* can't find valid BIOS pin config */
 
-       if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-           (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-           (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
-           (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+       err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
+       if (err < 0)
+               return err;
+       err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
 
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
        SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
+       SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
        SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
+       SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
        SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
        {}
 };
@@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = {
        },
        [ALC861_TOSHIBA] = {
                .mixers = { alc861_toshiba_mixer },
-               .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
+               .init_verbs = { alc861_base_init_verbs,
+                               alc861_toshiba_init_verbs },
                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
                .dac_nids = alc861_dac_nids,
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
@@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec)
        if (spec == NULL)
                return -ENOMEM;
 
-       codec->spec = spec;     
+       codec->spec = spec;
 
         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
                                                  alc861_models,
@@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
        idx = ucontrol->value.enumerated.item[0];
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
-       if (*cur_val == idx && ! codec->in_resume)
+       if (*cur_val == idx && !codec->in_resume)
                return 0;
        for (i = 0; i < imux->num_items; i++) {
                unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
+       HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+
+       HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+
+       { } /* end */
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 
        /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
-       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)},
 
        /*
         * Set up output mixers (0x02 - 0x05)
@@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
        { }
 };
 
+static struct hda_verb alc861vd_eapd_verbs[] = {
+       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+       { }
+};
+
+static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
+       {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x1b, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x18, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+                                0x80, bits);
+}
+
+static void alc861vd_lenovo_automute(struct hda_codec *codec)
+{
+       alc861vd_lenovo_hp_automute(codec);
+       alc861vd_lenovo_mic_automute(codec);
+}
+
+static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
+                                       unsigned int res)
+{
+       switch (res >> 26) {
+       case ALC880_HP_EVENT:
+               alc861vd_lenovo_hp_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc861vd_lenovo_mic_automute(codec);
+               break;
+       }
+}
+
 /* pcm configuration: identiacal with ALC880 */
 #define alc861vd_pcm_analog_playback   alc880_pcm_analog_playback
 #define alc861vd_pcm_analog_capture    alc880_pcm_analog_capture
@@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
        [ALC861VD_3ST]          = "3stack",
        [ALC861VD_3ST_DIG]      = "3stack-digout",
        [ALC861VD_6ST_DIG]      = "6stack-digout",
+       [ALC861VD_LENOVO]       = "lenovo",
        [ALC861VD_AUTO]         = "auto",
 };
 
 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
-       SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST),
+       SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
+       SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
        {}
 };
 
@@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = {
                .channel_mode = alc861vd_6stack_modes,
                .input_mux = &alc861vd_capture_source,
        },
+       [ALC861VD_LENOVO] = {
+               .mixers = { alc861vd_lenovo_mixer },
+               .init_verbs = { alc861vd_volume_init_verbs,
+                               alc861vd_3stack_init_verbs,
+                               alc861vd_eapd_verbs,
+                               alc861vd_lenovo_unsol_verbs },
+               .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
+               .dac_nids = alc660vd_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+               .adc_nids = alc861vd_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+               .channel_mode = alc861vd_3stack_2ch_modes,
+               .input_mux = &alc861vd_capture_source,
+               .unsol_event = alc861vd_lenovo_unsol_event,
+               .init_hook = alc861vd_lenovo_automute,
+       },
 };
 
 /*
@@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        int i;
 
+       alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
        for (i = 0; i <= HDA_SIDE; i++) {
                hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
                if (nid)
                        alc861vd_auto_set_output_and_unmute(codec, nid,
-                                                               PIN_OUT, i);
+                                                           pin_type, i);
        }
 }
 
@@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
        int i, err;
 
        for (i = 0; i < cfg->line_outs; i++) {
-               if (! spec->multiout.dac_nids[i])
+               if (!spec->multiout.dac_nids[i])
                        continue;
                nid_v = alc861vd_idx_to_mixer_vol(
                                alc880_dac_to_idx(
@@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 
                if (i == 2) {
                        /* Center/LFE */
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
-                                               "Center Playback Volume",
-                                               HDA_COMPOSE_AMP_VAL(nid_v, 1,
-                                                       0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "Center Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
-                                               "LFE Playback Volume",
-                                               HDA_COMPOSE_AMP_VAL(nid_v, 2,
-                                                       0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "LFE Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
-                                               "Center Playback Switch",
-                                               HDA_COMPOSE_AMP_VAL(nid_s, 1,
-                                               2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "Center Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
-                                               "LFE Playback Switch",
-                                               HDA_COMPOSE_AMP_VAL(nid_s, 2,
-                                               2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "LFE Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
                } else {
                        sprintf(name, "%s Playback Volume", chname[i]);
-                       if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                                               HDA_COMPOSE_AMP_VAL(nid_v, 3,
-                                                       0, HDA_OUTPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                         HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
                                return err;
                        sprintf(name, "%s Playback Switch", chname[i]);
-                       if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                                               HDA_COMPOSE_AMP_VAL(nid_v, 3,
-                                                       2, HDA_INPUT))) < 0)
+                       err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                         HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
                                return err;
                }
        }
@@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
        int err;
        char name[32];
 
-       if (! pin)
+       if (!pin)
                return 0;
 
        if (alc880_is_fixed_pin(pin)) {
                nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
                /* specify the DAC as the extra output */
-               if (! spec->multiout.hp_nid)
+               if (!spec->multiout.hp_nid)
                        spec->multiout.hp_nid = nid_v;
                else
                        spec->multiout.extra_out_nid[0] = nid_v;
@@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
                                alc880_fixed_pin_idx(pin));
 
                sprintf(name, "%s Playback Volume", pfx);
-               if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-                               HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
-                                                       HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
                sprintf(name, "%s Playback Switch", pfx);
-               if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-                               HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
-                                                       HDA_INPUT))) < 0)
+               err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
+               if (err < 0)
                        return err;
        } else if (alc880_is_multi_pin(pin)) {
                /* set manual connection */
                /* we have only a switch on HP-out PIN */
                sprintf(name, "%s Playback Switch", pfx);
-               if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-                               HDA_COMPOSE_AMP_VAL(pin, 3, 0,
-                                                       HDA_OUTPUT))) < 0)
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+               if (err < 0)
                        return err;
        }
        return 0;
@@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
        int err;
        static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
 
-       if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-                                               alc861vd_ignore)) < 0)
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc861vd_ignore);
+       if (err < 0)
                return err;
-       if (! spec->autocfg.line_outs)
+       if (!spec->autocfg.line_outs)
                return 0; /* can't find valid BIOS pin config */
 
-       if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-               (err = alc861vd_auto_create_multi_out_ctls(spec,
-                       &spec->autocfg)) < 0 ||
-               (err = alc861vd_auto_create_extra_out(spec,
-                       spec->autocfg.speaker_pins[0], "Speaker")) < 0 ||
-               (err = alc861vd_auto_create_extra_out(spec,
-                       spec->autocfg.hp_pins[0], "Headphone")) < 0 ||
-               (err = alc880_auto_create_analog_input_ctls(spec,
-                       &spec->autocfg)) < 0)
+       err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc861vd_auto_create_extra_out(spec,
+                                            spec->autocfg.speaker_pins[0],
+                                            "Speaker");
+       if (err < 0)
+               return err;
+       err = alc861vd_auto_create_extra_out(spec,
+                                            spec->autocfg.hp_pins[0],
+                                            "Headphone");
+       if (err < 0)
+               return err;
+       err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
                return err;
 
        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec)
                if (err < 0) {
                        alc_free(codec);
                        return err;
-               } else if (! err) {
+               } else if (!err) {
                        printk(KERN_INFO
                               "hda_codec: Cannot set up configuration "
                               "from BIOS.  Using base mode...\n");
@@ -8674,6 +9362,861 @@ static int patch_alc861vd(struct hda_codec *codec)
        return 0;
 }
 
+/*
+ * ALC662 support
+ *
+ * ALC662 is almost identical with ALC880 but has cleaner and more flexible
+ * configuration.  Each pin widget can choose any input DACs and a mixer.
+ * Each ADC is connected from a mixer of all inputs.  This makes possible
+ * 6-channel independent captures.
+ *
+ * In addition, an independent DAC for the multi-playback (not used in this
+ * driver yet).
+ */
+#define ALC662_DIGOUT_NID      0x06
+#define ALC662_DIGIN_NID       0x0a
+
+static hda_nid_t alc662_dac_nids[4] = {
+       /* front, rear, clfe, rear_surr */
+       0x02, 0x03, 0x04
+};
+
+static hda_nid_t alc662_adc_nids[1] = {
+       /* ADC1-2 */
+       0x09,
+};
+/* input MUX */
+/* FIXME: should be a matrix-type input source selection */
+
+static struct hda_input_mux alc662_capture_source = {
+       .num_items = 4,
+       .items = {
+               { "Mic", 0x0 },
+               { "Front Mic", 0x1 },
+               { "Line", 0x2 },
+               { "CD", 0x4 },
+       },
+};
+
+static struct hda_input_mux alc662_lenovo_101e_capture_source = {
+       .num_items = 2,
+       .items = {
+               { "Mic", 0x1 },
+               { "Line", 0x2 },
+       },
+};
+#define alc662_mux_enum_info alc_mux_enum_info
+#define alc662_mux_enum_get alc_mux_enum_get
+
+static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
+{
+       struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct alc_spec *spec = codec->spec;
+       const struct hda_input_mux *imux = spec->input_mux;
+       unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+       static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
+       hda_nid_t nid = capture_mixers[adc_idx];
+       unsigned int *cur_val = &spec->cur_mux[adc_idx];
+       unsigned int i, idx;
+
+       idx = ucontrol->value.enumerated.item[0];
+       if (idx >= imux->num_items)
+               idx = imux->num_items - 1;
+       if (*cur_val == idx && !codec->in_resume)
+               return 0;
+       for (i = 0; i < imux->num_items; i++) {
+               unsigned int v = (i == idx) ? 0x7000 : 0x7080;
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+                                   v | (imux->items[i].index << 8));
+       }
+       *cur_val = idx;
+       return 1;
+}
+/*
+ * 2ch mode
+ */
+static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
+       { 2, NULL }
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_3ST_ch2_init[] = {
+       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+       { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_3ST_ch6_init[] = {
+       { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+       { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
+       { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+       { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+       { } /* end */
+};
+
+static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
+       { 2, alc662_3ST_ch2_init },
+       { 6, alc662_3ST_ch6_init },
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_sixstack_ch6_init[] = {
+       { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+       { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_sixstack_ch8_init[] = {
+       { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+       { } /* end */
+};
+
+static struct hda_channel_mode alc662_5stack_modes[2] = {
+       { 2, alc662_sixstack_ch6_init },
+       { 6, alc662_sixstack_ch8_init },
+};
+
+/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
+ *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
+ */
+
+static struct snd_kcontrol_new alc662_base_mixer[] = {
+       /* output mixer control */
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+       /*Input mixer control */
+       HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
+
+       /* Capture mixer control */
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Capture Source",
+               .count = 1,
+               .info = alc_mux_enum_info,
+               .get = alc_mux_enum_get,
+               .put = alc_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc662_mux_enum_info,
+               .get = alc662_mux_enum_get,
+               .put = alc662_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc662_mux_enum_info,
+               .get = alc662_mux_enum_get,
+               .put = alc662_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc662_mux_enum_info,
+               .get = alc662_mux_enum_get,
+               .put = alc662_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_chmode_mixer[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Channel Mode",
+               .info = alc_ch_mode_info,
+               .get = alc_ch_mode_get,
+               .put = alc_ch_mode_put,
+       },
+       { } /* end */
+};
+
+static struct hda_verb alc662_init_verbs[] = {
+       /* ADC: mute amp left and right */
+       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+       /* Front mixer: unmute input/output amp left and right (volume = 0) */
+
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       /* Front Pin: output 0 (0x0c) */
+       {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+       /* Rear Pin: output 1 (0x0d) */
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+       /* CLFE Pin: output 2 (0x0e) */
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+       /* Mic (rear) pin: input vref at 80% */
+       {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+       {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* Front Mic pin: input vref at 80% */
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* Line In pin: input */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* Line-2 In: Headphone output (output 0 - 0x0c) */
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+       /* CD pin widget for input */
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+
+       /* FIXME: use matrix-type input source selection */
+       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+       /* Input mixer */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+       { }
+};
+
+static struct hda_verb alc662_sue_init_verbs[] = {
+       {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
+        {}
+};
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc662_auto_init_verbs[] = {
+       /*
+        * Unmute ADC and set the default input to mic-in
+        */
+       {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+       /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+        * mixer widget
+        * Note: PASD motherboards uses the Line In 2 as the input for front
+        * panel mic (mic 2)
+        */
+       /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+       {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+       /*
+        * Set up output mixers (0x0c - 0x0f)
+        */
+       /* set vol=0 to output mixers */
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+       /* set up input amps for analog loopback */
+       /* Amp Indices: DAC = 0, mixer = 1 */
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+
+       /* FIXME: use matrix-type input source selection */
+       /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+       /* Input mixer */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+       /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
+       {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+       { }
+};
+
+/* capture mixer elements */
+static struct snd_kcontrol_new alc662_capture_mixer[] = {
+       HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               /* The multiple "Capture Source" controls confuse alsamixer
+                * So call somewhat different..
+                * FIXME: the controls appear in the "playback" view!
+                */
+               /* .name = "Capture Source", */
+               .name = "Input Source",
+               .count = 1,
+               .info = alc882_mux_enum_info,
+               .get = alc882_mux_enum_get,
+               .put = alc882_mux_enum_put,
+       },
+       { } /* end */
+};
+
+static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x14, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+       unsigned int present;
+       unsigned char bits;
+
+       present = snd_hda_codec_read(codec, 0x1b, 0,
+                                    AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+       bits = present ? 0x80 : 0;
+       snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+                                0x80, bits);
+       snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+                                0x80, bits);
+}
+
+static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       if ((res >> 26) == ALC880_HP_EVENT)
+               alc662_lenovo_101e_all_automute(codec);
+       if ((res >> 26) == ALC880_FRONT_EVENT)
+               alc662_lenovo_101e_ispeaker_automute(codec);
+}
+
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc662_pcm_analog_playback     alc880_pcm_analog_playback
+#define alc662_pcm_analog_capture      alc880_pcm_analog_capture
+#define alc662_pcm_digital_playback    alc880_pcm_digital_playback
+#define alc662_pcm_digital_capture     alc880_pcm_digital_capture
+
+/*
+ * configuration and preset
+ */
+static const char *alc662_models[ALC662_MODEL_LAST] = {
+       [ALC662_3ST_2ch_DIG]    = "3stack-dig",
+       [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
+       [ALC662_3ST_6ch]        = "3stack-6ch",
+       [ALC662_5ST_DIG]        = "6stack-dig",
+       [ALC662_LENOVO_101E]    = "lenovo-101e",
+       [ALC662_AUTO]           = "auto",
+};
+
+static struct snd_pci_quirk alc662_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+       {}
+};
+
+static struct alc_config_preset alc662_presets[] = {
+       [ALC662_3ST_2ch_DIG] = {
+               .mixers = { alc662_3ST_2ch_mixer },
+               .init_verbs = { alc662_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .dig_out_nid = ALC662_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .dig_in_nid = ALC662_DIGIN_NID,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+               .channel_mode = alc662_3ST_2ch_modes,
+               .input_mux = &alc662_capture_source,
+       },
+       [ALC662_3ST_6ch_DIG] = {
+               .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+               .init_verbs = { alc662_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .dig_out_nid = ALC662_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .dig_in_nid = ALC662_DIGIN_NID,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+               .channel_mode = alc662_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc662_capture_source,
+       },
+       [ALC662_3ST_6ch] = {
+               .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+               .init_verbs = { alc662_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+               .channel_mode = alc662_3ST_6ch_modes,
+               .need_dac_fix = 1,
+               .input_mux = &alc662_capture_source,
+       },
+       [ALC662_5ST_DIG] = {
+               .mixers = { alc662_base_mixer, alc662_chmode_mixer },
+               .init_verbs = { alc662_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .dig_out_nid = ALC662_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .dig_in_nid = ALC662_DIGIN_NID,
+               .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
+               .channel_mode = alc662_5stack_modes,
+               .input_mux = &alc662_capture_source,
+       },
+       [ALC662_LENOVO_101E] = {
+               .mixers = { alc662_lenovo_101e_mixer },
+               .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .dac_nids = alc662_dac_nids,
+               .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+               .adc_nids = alc662_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+               .channel_mode = alc662_3ST_2ch_modes,
+               .input_mux = &alc662_lenovo_101e_capture_source,
+               .unsol_event = alc662_lenovo_101e_unsol_event,
+               .init_hook = alc662_lenovo_101e_all_automute,
+       },
+
+};
+
+
+/*
+ * BIOS auto configuration
+ */
+
+/* add playback controls from the parsed DAC table */
+static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+                                            const struct auto_pin_cfg *cfg)
+{
+       char name[32];
+       static const char *chname[4] = {
+               "Front", "Surround", NULL /*CLFE*/, "Side"
+       };
+       hda_nid_t nid;
+       int i, err;
+
+       for (i = 0; i < cfg->line_outs; i++) {
+               if (!spec->multiout.dac_nids[i])
+                       continue;
+               nid = alc880_idx_to_dac(i);
+               if (i == 2) {
+                       /* Center/LFE */
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "Center Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
+                               return err;
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL,
+                                         "LFE Playback Volume",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
+                               return err;
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "Center Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
+                               return err;
+                       err = add_control(spec, ALC_CTL_BIND_MUTE,
+                                         "LFE Playback Switch",
+                                         HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
+                               return err;
+               } else {
+                       sprintf(name, "%s Playback Volume", chname[i]);
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+                                                             HDA_OUTPUT));
+                       if (err < 0)
+                               return err;
+                       sprintf(name, "%s Playback Switch", chname[i]);
+                       err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                         HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+                                                             HDA_INPUT));
+                       if (err < 0)
+                               return err;
+               }
+       }
+       return 0;
+}
+
+/* add playback controls for speaker and HP outputs */
+static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+                                       const char *pfx)
+{
+       hda_nid_t nid;
+       int err;
+       char name[32];
+
+       if (!pin)
+               return 0;
+
+       if (alc880_is_fixed_pin(pin)) {
+               nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+                /* printk("DAC nid=%x\n",nid); */
+               /* specify the DAC as the extra output */
+               if (!spec->multiout.hp_nid)
+                       spec->multiout.hp_nid = nid;
+               else
+                       spec->multiout.extra_out_nid[0] = nid;
+               /* control HP volume/switch on the output mixer amp */
+               nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+               sprintf(name, "%s Playback Volume", pfx);
+               err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+               if (err < 0)
+                       return err;
+               sprintf(name, "%s Playback Switch", pfx);
+               err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+               if (err < 0)
+                       return err;
+       } else if (alc880_is_multi_pin(pin)) {
+               /* set manual connection */
+               /* we have only a switch on HP-out PIN */
+               sprintf(name, "%s Playback Switch", pfx);
+               err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+                                 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
+                                               const struct auto_pin_cfg *cfg)
+{
+       struct hda_input_mux *imux = &spec->private_imux;
+       int i, err, idx;
+
+       for (i = 0; i < AUTO_PIN_LAST; i++) {
+               if (alc880_is_input_pin(cfg->input_pins[i])) {
+                       idx = alc880_input_pin_idx(cfg->input_pins[i]);
+                       err = new_analog_input(spec, cfg->input_pins[i],
+                                              auto_pin_cfg_labels[i],
+                                              idx, 0x0b);
+                       if (err < 0)
+                               return err;
+                       imux->items[imux->num_items].label =
+                               auto_pin_cfg_labels[i];
+                       imux->items[imux->num_items].index =
+                               alc880_input_pin_idx(cfg->input_pins[i]);
+                       imux->num_items++;
+               }
+       }
+       return 0;
+}
+
+static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
+                                             hda_nid_t nid, int pin_type,
+                                             int dac_idx)
+{
+       /* set as output */
+       snd_hda_codec_write(codec, nid, 0,
+                           AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+       snd_hda_codec_write(codec, nid, 0,
+                           AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+       /* need the manual connection? */
+       if (alc880_is_multi_pin(nid)) {
+               struct alc_spec *spec = codec->spec;
+               int idx = alc880_multi_pin_idx(nid);
+               snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
+                                   AC_VERB_SET_CONNECT_SEL,
+                                   alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+       }
+}
+
+static void alc662_auto_init_multi_out(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int i;
+
+       for (i = 0; i <= HDA_SIDE; i++) {
+               hda_nid_t nid = spec->autocfg.line_out_pins[i];
+               int pin_type = get_pin_type(spec->autocfg.line_out_type);
+               if (nid)
+                       alc662_auto_set_output_and_unmute(codec, nid, pin_type,
+                                                         i);
+       }
+}
+
+static void alc662_auto_init_hp_out(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       hda_nid_t pin;
+
+       pin = spec->autocfg.hp_pins[0];
+       if (pin) /* connect to front */
+               /* use dac 0 */
+               alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+}
+
+#define alc662_is_input_pin(nid)       alc880_is_input_pin(nid)
+#define ALC662_PIN_CD_NID              ALC880_PIN_CD_NID
+
+static void alc662_auto_init_analog_input(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int i;
+
+       for (i = 0; i < AUTO_PIN_LAST; i++) {
+               hda_nid_t nid = spec->autocfg.input_pins[i];
+               if (alc662_is_input_pin(nid)) {
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
+                                           (i <= AUTO_PIN_FRONT_MIC ?
+                                            PIN_VREF80 : PIN_IN));
+                       if (nid != ALC662_PIN_CD_NID)
+                               snd_hda_codec_write(codec, nid, 0,
+                                                   AC_VERB_SET_AMP_GAIN_MUTE,
+                                                   AMP_OUT_MUTE);
+               }
+       }
+}
+
+static int alc662_parse_auto_config(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int err;
+       static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
+
+       err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+                                          alc662_ignore);
+       if (err < 0)
+               return err;
+       if (!spec->autocfg.line_outs)
+               return 0; /* can't find valid BIOS pin config */
+
+       err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       err = alc662_auto_create_extra_out(spec,
+                                          spec->autocfg.speaker_pins[0],
+                                          "Speaker");
+       if (err < 0)
+               return err;
+       err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+                                          "Headphone");
+       if (err < 0)
+               return err;
+       err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
+       if (err < 0)
+               return err;
+
+       spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+       if (spec->autocfg.dig_out_pin)
+               spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
+
+       if (spec->kctl_alloc)
+               spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+       spec->num_mux_defs = 1;
+       spec->input_mux = &spec->private_imux;
+       
+       if (err < 0)
+               return err;
+       else if (err > 0)
+               /* hack - override the init verbs */
+               spec->init_verbs[0] = alc662_auto_init_verbs;
+       spec->mixers[spec->num_mixers] = alc662_capture_mixer;
+       spec->num_mixers++;
+       return err;
+}
+
+/* additional initialization for auto-configuration model */
+static void alc662_auto_init(struct hda_codec *codec)
+{
+       alc662_auto_init_multi_out(codec);
+       alc662_auto_init_hp_out(codec);
+       alc662_auto_init_analog_input(codec);
+}
+
+static int patch_alc662(struct hda_codec *codec)
+{
+       struct alc_spec *spec;
+       int err, board_config;
+
+       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+       if (!spec)
+               return -ENOMEM;
+
+       codec->spec = spec;
+
+       board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
+                                                 alc662_models,
+                                                 alc662_cfg_tbl);
+       if (board_config < 0) {
+               printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
+                      "trying auto-probe from BIOS...\n");
+               board_config = ALC662_AUTO;
+       }
+
+       if (board_config == ALC662_AUTO) {
+               /* automatic parse from the BIOS config */
+               err = alc662_parse_auto_config(codec);
+               if (err < 0) {
+                       alc_free(codec);
+                       return err;
+               } else if (err) {
+                       printk(KERN_INFO
+                              "hda_codec: Cannot set up configuration "
+                              "from BIOS.  Using base mode...\n");
+                       board_config = ALC662_3ST_2ch_DIG;
+               }
+       }
+
+       if (board_config != ALC662_AUTO)
+               setup_preset(spec, &alc662_presets[board_config]);
+
+       spec->stream_name_analog = "ALC662 Analog";
+       spec->stream_analog_playback = &alc662_pcm_analog_playback;
+       spec->stream_analog_capture = &alc662_pcm_analog_capture;
+
+       spec->stream_name_digital = "ALC662 Digital";
+       spec->stream_digital_playback = &alc662_pcm_digital_playback;
+       spec->stream_digital_capture = &alc662_pcm_digital_capture;
+
+       if (!spec->adc_nids && spec->input_mux) {
+               spec->adc_nids = alc662_adc_nids;
+               spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
+       }
+
+       codec->patch_ops = alc_patch_ops;
+       if (board_config == ALC662_AUTO)
+               spec->init_hook = alc662_auto_init;
+
+       return 0;
+}
+
 /*
  * patch entries
  */
@@ -8681,10 +10224,14 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
-               .patch = patch_alc861 },
+         .patch = patch_alc861 },
        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
+       { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
+         .patch = patch_alc883 },
+       { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
+         .patch = patch_alc662 },
        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
        { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
index c94291bc53677c36c62c0109bd0537cee79b40cb..93ae9c2507677c4e75837c8357dafc32aa799cdf 100644 (file)
@@ -62,6 +62,7 @@ enum {
        STAC_MACBOOK,
        STAC_MACBOOK_PRO_V1,
        STAC_MACBOOK_PRO_V2,
+       STAC_IMAC_INTEL,
        STAC_922X_MODELS
 };
 
@@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = {
         0x19, 0x1a
 };
 
-static hda_nid_t stac9205_dmic_nids[3] = {
-        0x17, 0x18, 0
+static hda_nid_t stac9205_dmic_nids[2] = {
+        0x17, 0x18,
 };
 
 static hda_nid_t stac9200_pin_nids[8] = {
@@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = {
        0x02a19320, 0x40000100,
 };
 
-static unsigned int macbook_pin_configs[10] = {
-       0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110,
-       0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e,
-       0x400000fc, 0x400000fb,
-};
-
 static unsigned int macbook_pro_v1_pin_configs[10] = {
        0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010,
        0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e,
@@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = {
        0x400000fc, 0x400000fb,
 };
 
+static unsigned int imac_intel_pin_configs[10] = {
+       0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe,
+       0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa,
+       0x400000fc, 0x400000fb,
+};
+
 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
        [STAC_D945_REF] = ref922x_pin_configs,
        [STAC_D945GTP3] = d945gtp3_pin_configs,
        [STAC_D945GTP5] = d945gtp5_pin_configs,
-       [STAC_MACMINI] = d945gtp5_pin_configs,
-       [STAC_MACBOOK] = macbook_pin_configs,
+       [STAC_MACMINI] = macbook_pro_v1_pin_configs,
+       [STAC_MACBOOK] = macbook_pro_v1_pin_configs,
        [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs,
        [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs,
+       [STAC_IMAC_INTEL] = imac_intel_pin_configs,
 };
 
 static const char *stac922x_models[STAC_922X_MODELS] = {
@@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
        [STAC_MACBOOK]  = "macbook",
        [STAC_MACBOOK_PRO_V1]   = "macbook-pro-v1",
        [STAC_MACBOOK_PRO_V2]   = "macbook-pro",
+       [STAC_IMAC_INTEL] = "imac-intel",
 };
 
 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                        struct hda_codec *codec,
+                                        unsigned int stream_tag,
+                                        unsigned int format,
+                                        struct snd_pcm_substream *substream)
+{
+       struct sigmatel_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+                                            stream_tag, format, substream);
+}
+
 
 /*
  * Analog capture callbacks
@@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
        /* NID is set in stac92xx_build_pcms */
        .ops = {
                .open = stac92xx_dig_playback_pcm_open,
-               .close = stac92xx_dig_playback_pcm_close
+               .close = stac92xx_dig_playback_pcm_close,
+               .prepare = stac92xx_dig_playback_pcm_prepare
        },
 };
 
@@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
 {
        struct sigmatel_spec *spec = codec->spec;
+       unsigned int wcaps, wtype;
+       int i, num_dacs = 0;
+       
+       /* use the wcaps cache to count all DACs available for line-outs */
+       for (i = 0; i < codec->num_nodes; i++) {
+               wcaps = codec->wcaps[i];
+               wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+               if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
+                       num_dacs++;
+       }
 
+       snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
+       
        switch (cfg->line_outs) {
        case 3:
                /* add line-in as side */
-               if (cfg->input_pins[AUTO_PIN_LINE]) {
+               if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
                        cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
                        spec->line_switch = 1;
                        cfg->line_outs++;
@@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
                break;
        case 2:
                /* add line-in as clfe and mic as side */
-               if (cfg->input_pins[AUTO_PIN_LINE]) {
+               if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
                        cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
                        spec->line_switch = 1;
                        cfg->line_outs++;
                }
-               if (cfg->input_pins[AUTO_PIN_MIC]) {
+               if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
                        cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
                        spec->mic_switch = 1;
                        cfg->line_outs++;
@@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
                break;
        case 1:
                /* add line-in as surr and mic as clfe */
-               if (cfg->input_pins[AUTO_PIN_LINE]) {
+               if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
                        cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
                        spec->line_switch = 1;
                        cfg->line_outs++;
                }
-               if (cfg->input_pins[AUTO_PIN_MIC]) {
+               if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
                        cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
                        spec->mic_switch = 1;
                        cfg->line_outs++;
@@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
        return 0;
 }
 
+
+static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
+{
+       int i;
+       
+       for (i = 0; i < spec->multiout.num_dacs; i++) {
+               if (spec->multiout.dac_nids[i] == nid)
+                       return 1;
+       }
+
+       return 0;
+}
+
 /*
- * XXX The line_out pin widget connection list may not be set to the
- * desired DAC nid. This is the case on 927x where ports A and B can
- * be routed to several DACs.
- *
- * This requires an analysis of the line-out/hp pin configuration
- * to provide a best fit for pin/DAC configurations that are routable.
- * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
- * A and B is not supported.
+ * Fill in the dac_nids table from the parsed pin configuration
+ * This function only works when every pin in line_out_pins[]
+ * contains atleast one DAC in its connection list. Some 92xx
+ * codecs are not connected directly to a DAC, such as the 9200
+ * and 9202/925x. For those, dac_nids[] must be hard-coded.
  */
-/* fill in the dac_nids table from the parsed pin configuration */
 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
                                       const struct auto_pin_cfg *cfg)
 {
        struct sigmatel_spec *spec = codec->spec;
-       hda_nid_t nid;
-       int i;
-
-       /* check the pins hardwired to audio widget */
+       int i, j, conn_len = 0; 
+       hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
+       unsigned int wcaps, wtype;
+       
        for (i = 0; i < cfg->line_outs; i++) {
                nid = cfg->line_out_pins[i];
-               spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
-                                       AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
-       }
+               conn_len = snd_hda_get_connections(codec, nid, conn,
+                                                  HDA_MAX_CONNECTIONS);
+               for (j = 0; j < conn_len; j++) {
+                       wcaps = snd_hda_param_read(codec, conn[j],
+                                                  AC_PAR_AUDIO_WIDGET_CAP);
+                       wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+
+                       if (wtype != AC_WID_AUD_OUT ||
+                           (wcaps & AC_WCAP_DIGITAL))
+                               continue;
+                       /* conn[j] is a DAC routed to this line-out */
+                       if (!is_in_dac_nids(spec, conn[j]))
+                               break;
+               }
+
+               if (j == conn_len) {
+                       /* error out, no available DAC found */
+                       snd_printk(KERN_ERR
+                                  "%s: No available DAC for pin 0x%x\n",
+                                  __func__, nid);
+                       return -ENODEV;
+               }
 
-       spec->multiout.num_dacs = cfg->line_outs;
+               spec->multiout.dac_nids[i] = conn[j];
+               spec->multiout.num_dacs++;
+               if (conn_len > 1) {
+                       /* select this DAC in the pin's input mux */
+                       snd_hda_codec_write(codec, nid, 0,
+                                           AC_VERB_SET_CONNECT_SEL, j);
+
+               }
+       }
 
+       snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
+                  spec->multiout.num_dacs,
+                  spec->multiout.dac_nids[0],
+                  spec->multiout.dac_nids[1],
+                  spec->multiout.dac_nids[2],
+                  spec->multiout.dac_nids[3],
+                  spec->multiout.dac_nids[4]);
        return 0;
 }
 
@@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
 
 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
 {
-       int i;
-
-       for (i = 0; i < spec->multiout.num_dacs; i++) {
-               if (spec->multiout.dac_nids[i] == nid)
-                       return 1;
-       }
+       if (is_in_dac_nids(spec, nid))
+               return 1;
        if (spec->multiout.hp_nid == nid)
                return 1;
        return 0;
@@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
                add_spec_dacs(spec, nid);
        }
        for (i = 0; i < cfg->speaker_outs; i++) {
-               nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0,
+               nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
                                         AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
                if (check_in_dac_nids(spec, nid))
                        nid = 0;
-               if (check_in_dac_nids(spec, nid))
-                       nid = 0;
                if (! nid)
                        continue;
                add_spec_dacs(spec, nid);
@@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
                imux->num_items++;
        }
 
-       if (imux->num_items == 1) {
+       if (imux->num_items) {
                /*
                 * Set the current input for the muxes.
                 * The STAC9221 has two input muxes with identical source
@@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
 {
        unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
-       if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN))
-               return;
+
+       /* if setting pin direction bits, clear the current
+          direction bits first */
+       if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
+               pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
+       
        snd_hda_codec_write(codec, nid, 0,
                        AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pin_ctl | flag);
@@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec)
 
        stac92xx_init(codec);
        stac92xx_set_config_regs(codec);
+       snd_hda_resume_ctls(codec, spec->mixer);
        for (i = 0; i < spec->num_mixers; i++)
                snd_hda_resume_ctls(codec, spec->mixers[i]);
        if (spec->multiout.dig_out_nid)
@@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec)
                 */
                printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
                switch (codec->subsystem_id) {
+               case 0x106b0a00: /* MacBook First generatoin */
+                       spec->board_config = STAC_MACBOOK;
+                       break;
                case 0x106b0200: /* MacBook Pro first generation */
                        spec->board_config = STAC_MACBOOK_PRO_V1;
                        break;
                case 0x106b1e00: /* MacBook Pro second generation */
                        spec->board_config = STAC_MACBOOK_PRO_V2;
                        break;
+               case 0x106b0700: /* Intel-based iMac */
+                       spec->board_config = STAC_IMAC_INTEL;
+                       break;
                }
        }
 
@@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec)
 
        spec->adc_nids = stac922x_adc_nids;
        spec->mux_nids = stac922x_mux_nids;
-       spec->num_muxes = 2;
+       spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
        spec->num_dmics = 0;
 
        spec->init = stac922x_core_init;
@@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec)
        case STAC_D965_3ST:
                spec->adc_nids = stac927x_adc_nids;
                spec->mux_nids = stac927x_mux_nids;
-               spec->num_muxes = 3;
+               spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
                spec->num_dmics = 0;
                spec->init = d965_core_init;
                spec->mixer = stac9227_mixer;
@@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec)
        case STAC_D965_5ST:
                spec->adc_nids = stac927x_adc_nids;
                spec->mux_nids = stac927x_mux_nids;
-               spec->num_muxes = 3;
+               spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
                spec->num_dmics = 0;
                spec->init = d965_core_init;
                spec->mixer = stac9227_mixer;
@@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec)
        default:
                spec->adc_nids = stac927x_adc_nids;
                spec->mux_nids = stac927x_mux_nids;
-               spec->num_muxes = 3;
+               spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
                spec->num_dmics = 0;
                spec->init = stac927x_core_init;
                spec->mixer = stac927x_mixer;
@@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec)
 
        spec->adc_nids = stac9205_adc_nids;
        spec->mux_nids = stac9205_mux_nids;
-       spec->num_muxes = 2;
+       spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
        spec->dmic_nids = stac9205_dmic_nids;
-       spec->num_dmics = 2;
+       spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
        spec->dmux_nid = 0x1d;
 
        spec->init = stac9205_core_init;
@@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
        SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
        SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
+       SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
        {}
 };
 
index 2b11ac8689b99690ff14112f2f5ba7cd2a77320b..ba32d1e52cb84d52b4f3a0b9087ab2ae2588a55d 100644 (file)
@@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+                                       struct hda_codec *codec,
+                                       unsigned int stream_tag,
+                                       unsigned int format,
+                                       struct snd_pcm_substream *substream)
+{
+       struct via_spec *spec = codec->spec;
+       return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+                                            stream_tag, format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
        /* NID is set in via_build_pcms */
        .ops = {
                .open = via_dig_playback_pcm_open,
-               .close = via_dig_playback_pcm_close
+               .close = via_dig_playback_pcm_close,
+               .prepare = via_dig_playback_pcm_prepare
        },
 };
 
index 6e22d326df328ad04bfa00a1c2c31f80406a212b..44bbb630b949076505cc3591606e663eeb2525ac 100644 (file)
@@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_AV710,
                .name = "Chaintech AV-710",
index 7b667bad0c6ba17c98a2405cae81983d1b1b45f9..a0fc89b48122d4a65779acec06542eb90d90a293 100644 (file)
@@ -42,7 +42,7 @@
 #define WM_DAC_CTRL    0x02
 #define WM_INT_CTRL    0x03
 
-extern const struct snd_ice1712_card_info  snd_vt1724_amp_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_amp_cards[];
 
 
 #endif /* __SOUND_AMP_H */
index 6941d85dfec9d669c6da90db6fd6de45821f0d55..66bacde1ead3cf9d55c063a475b3e9c261f8f1c9 100644 (file)
@@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
  * mixers
  */
 
-static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
@@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
        }
 };
 
-static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "PCM Playback Switch",
@@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
        }
 };
 
-static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "AC97 Playback Switch",
@@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
        }
 };
 
-static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "AC97 Playback Switch",
@@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
 
 };
 
-static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
+static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
  * hence the driver needs to sets up it properly.
  */
 
-static const unsigned char aureon51_eeprom[] __devinitdata = {
+static unsigned char aureon51_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x0a,  /* clock 512, spdif-in/ADC, 3DACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
@@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = {
        [ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static const unsigned char aureon71_eeprom[] __devinitdata = {
+static unsigned char aureon71_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x0b,  /* clock 512, spdif-in/ADC, 4DACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
@@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = {
 };
 #define prodigy71_eeprom aureon71_eeprom
 
-static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
+static unsigned char prodigy71lt_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x4b,  /* clock 384, spdif-in/ADC, 4DACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
@@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
 #define prodigy71xt_eeprom prodigy71lt_eeprom
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
                .name = "Terratec Aureon 5.1-Sky",
index 79e58e88ed473228bd2106713247eee06c1795e8..c253b8e2c789bd8988f44335330a5f9304e2ed53 100644 (file)
@@ -38,7 +38,7 @@
 #define VT1724_SUBDEVICE_PRODIGY71LT   0x32315441      /* PRODIGY 7.1 LT */
 #define VT1724_SUBDEVICE_PRODIGY71XT   0x36315441      /* PRODIGY 7.1 XT*/
 
-extern const struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];
 
 /* GPIO bits */
 #define AUREON_CS8415_CS       (1 << 22)
index 3eeb36c6e98551be3a735e38747a1239b27222b5..af659800c9b040579d03a04bc44b6400af56f588 100644 (file)
@@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
 {
        .access =       (SNDRV_CTL_ELEM_ACCESS_READ),
        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __
  * initialize the chips on M-Audio cards
  */
 
-static const struct snd_akm4xxx akm_audiophile __devinitdata = {
+static struct snd_akm4xxx akm_audiophile __devinitdata = {
        .type = SND_AK4528,
        .num_adcs = 2,
        .num_dacs = 2,
@@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
        .caddr = 2,
        .cif = 0,
        .data_mask = ICE1712_DELTA_AP_DOUT,
@@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta410 __devinitdata = {
+static struct snd_akm4xxx akm_delta410 __devinitdata = {
        .type = SND_AK4529,
        .num_adcs = 2,
        .num_dacs = 8,
@@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
        .caddr = 0,
        .cif = 0,
        .data_mask = ICE1712_DELTA_AP_DOUT,
@@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
+static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
        .type = SND_AK4524,
        .num_adcs = 8,
        .num_dacs = 8,
@@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
        .caddr = 2,
        .cif = 0, /* the default level of the CIF pin from AK4524 */
        .data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta44 __devinitdata = {
+static struct snd_akm4xxx akm_delta44 __devinitdata = {
        .type = SND_AK4524,
        .num_adcs = 4,
        .num_dacs = 4,
@@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
        .caddr = 2,
        .cif = 0, /* the default level of the CIF pin from AK4524 */
        .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_vx442 __devinitdata = {
+static struct snd_akm4xxx akm_vx442 __devinitdata = {
        .type = SND_AK4524,
        .num_adcs = 4,
        .num_dacs = 4,
@@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
        .caddr = 2,
        .cif = 0,
        .data_mask = ICE1712_VX442_DOUT,
@@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
  * additional controls for M-Audio cards
  */
 
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
 
 
@@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
        {
                .subvendor = ICE1712_SUBDEVICE_DELTA1010,
                .name = "M Audio Delta 1010",
index e47861ccd6e75fd94718d3454a15f152268592d6..2697156607e454093636a8fe773bdb77dbdd8682 100644 (file)
@@ -46,7 +46,7 @@
 #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
 
 
 /*
index 9b7ff302c0725dd9aea8226500d36b11f0773d8a..b135389fec6c7cbc83e69a73f9f05f5cdf1272ef 100644 (file)
@@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
 
 /*
  */
-static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
+static struct snd_akm4xxx akm_ews88mt __devinitdata = {
        .num_adcs = 8,
        .num_dacs = 8,
        .type = SND_AK4524,
@@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
        .caddr = 2,
        .cif = 1, /* CIF high */
        .data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
+static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
        .num_adcs = 2,
        .num_dacs = 2,
        .type = SND_AK4524,
@@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
        .caddr = 2,
        .cif = 1, /* CIF high */
        .data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_6fire __devinitdata = {
+static struct snd_akm4xxx akm_6fire __devinitdata = {
        .num_adcs = 6,
        .num_dacs = 6,
        .type = SND_AK4524,
@@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = {
        }
 };
 
-static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
        .caddr = 2,
        .cif = 1, /* CIF high */
        .data_mask = ICE1712_6FIRE_SERIAL_DATA,
@@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn
        return val != nval;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Input Sensitivity Switch",
@@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
        return ndata != data;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Input Sensitivity Switch",
        .info = snd_ice1712_ewx_io_sense_info,
@@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda
        .count = 8,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Output Sensitivity Switch",
        .info = snd_ice1712_ewx_io_sense_info,
@@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
   .private_value = xshift | (xinvert << 8),\
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
        EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
        EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
        EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
   .private_value = xshift | (xinvert << 8),\
 }
 
-static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Analog Input Select",
@@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
        {
                .subvendor = ICE1712_SUBDEVICE_EWX2496,
                .name = "TerraTec EWX24/96",
index df449b4741f6303ce3f6d84a488afeee4827ff02..a12a0b053558b3db17d7ace7a97078cebdaa1d9b 100644 (file)
@@ -40,7 +40,7 @@
 #define ICE1712_SUBDEVICE_PHASE88      0x3b155111
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
 
 
 /* TerraTec EWX 24/96 configuration definitions */
index df97313aaf83cdd368e706707de198e3fad82aa2..8203562ef7e7b346681ae1c85b9dad007349708f 100644 (file)
@@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
 {
        /* Hoontech STDSP24 with modified hardware */
-       static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
+       static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
                .num_adcs = 2,
                .num_dacs = 2,
                .type = SND_AK4524,
@@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
                }
        };
 
-       static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
+       static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
                .caddr = 2,
                .cif = 1, /* CIF high */
                .data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
        {
                .subvendor = ICE1712_SUBDEVICE_STDSP24,
                .name = "Hoontech SoundTrack Audio DSP24",
index b62d6e4f6c7107bba95ddb373837b2075f8be959..1ee538b20fbfafe5767b4adb64b85225c2ba6cfa 100644 (file)
@@ -35,7 +35,7 @@
 #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1     0x16141217      /* Hoontech ST Audio DSP24 Media 7.1 */
 #define ICE1712_SUBDEVICE_EVENT_EZ8            0x00010001      /* A dummy id for EZ8 */
 
-extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
 
 
 /* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
index 830a1bbd7110a058ba2765a913eda0c34849f27d..6630a0ae95276b3b74e1ca10fbcc1c396f241a30 100644 (file)
@@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
        return val != nval;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Digital Mixer To AC97",
        .info = snd_ice1712_digmix_route_ac97_info,
@@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
        {
                unsigned int what = 0;
                unsigned int old;
-               struct list_head *pos;
                struct snd_pcm_substream *s;
 
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == ice->playback_pro_substream) {
                                what |= ICE1712_PLAYBACK_START;
                                snd_pcm_trigger_done(s, substream);
@@ -1380,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc
 
 static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0);
 
-static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Multi Playback Switch",
@@ -1404,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini
        },
 };
 
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "H/W Multi Capture Switch",
        .info = snd_ice1712_pro_mixer_switch_info,
@@ -1413,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d
        .private_value = 10,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),
        .info = snd_ice1712_pro_mixer_switch_info,
@@ -1423,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de
        .count = 2,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
                   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1435,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d
        .tlv = { .p = db_scale_playback }
 };
 
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),
        .info = snd_ice1712_pro_mixer_volume_info,
@@ -1627,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_CARD,
        .name = "ICE1712 EEPROM",
        .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1663,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1714,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
 {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1723,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
        .get =          snd_ice1712_spdif_maskc_get,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
 {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1750,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
 {
        .access =       (SNDRV_CTL_ELEM_ACCESS_READWRITE |
                         SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1891,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Internal Clock",
        .info = snd_ice1712_pro_internal_clock_info,
@@ -1962,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Internal Clock Default",
        .info = snd_ice1712_pro_internal_clock_default_info,
@@ -2001,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Rate Locking",
        .info = snd_ice1712_pro_rate_locking_info,
@@ -2040,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Rate Reset",
        .info = snd_ice1712_pro_rate_reset_info,
@@ -2207,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "H/W Playback Route",
        .info = snd_ice1712_pro_route_info,
@@ -2215,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini
        .put = snd_ice1712_pro_route_analog_put,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
        .info = snd_ice1712_pro_route_info,
@@ -2257,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Volume Rate",
        .info = snd_ice1712_pro_volume_rate_info,
@@ -2290,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Peak",
        .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2305,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata =
 /*
  * list of available boards
  */
-static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
        snd_ice1712_hoontech_cards,
        snd_ice1712_delta_cards,
        snd_ice1712_ews_cards,
@@ -2329,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
 {
        int dev = 0xa0;         /* EEPROM device address */
        unsigned int i, size;
-       const struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (! modelname || ! *modelname) {
                ice->eeprom.subvendor = 0;
@@ -2658,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
  *
  */
 
-static const struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched __devinitdata;
 
 static int __devinit snd_ice1712_probe(struct pci_dev *pci,
                                       const struct pci_device_id *pci_id)
@@ -2667,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
        struct snd_card *card;
        struct snd_ice1712 *ice;
        int pcm_dev = 0, err;
-       const struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (dev >= SNDRV_CARDS)
                return -ENODEV;
index c3d9feaaf57df8363790e722107631fae6e0453f..6ac486d9c138a96dcdc50a23c21a5a770a6d6709 100644 (file)
@@ -397,6 +397,9 @@ struct snd_ice1712 {
                        struct ak4114 *ak4114;
                        unsigned int analog: 1;
                } juli;
+               struct {
+                       struct ak4114 *ak4114;
+               } prodigy192;
        } spec;
 
 };
index 1127ebdf5fec45971a41869d797229300fc2ba90..ee620dea7ef3ea621378c5f2988d0e3eff90472b 100644 (file)
@@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        unsigned char what;
        unsigned char old;
-       struct list_head *pos;
        struct snd_pcm_substream *s;
 
        what = 0;
-       snd_pcm_group_for_each(pos, substream) {
+       snd_pcm_group_for_each_entry(s, substream) {
                const struct vt1724_pcm_reg *reg;
-               s = snd_pcm_group_substream_entry(pos);
                reg = s->runtime->private_data;
                what |= reg->start;
                snd_pcm_trigger_done(s, substream);
@@ -1318,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_CARD,
        .name = "ICE1724 EEPROM",
        .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1431,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
        return (val != old);
 }
 
-static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1463,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
 {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1472,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
        .get =          snd_vt1724_spdif_maskc_get,
 };
 
-static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
 {
        .access =       SNDRV_CTL_ELEM_ACCESS_READ,
        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1517,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
        return old != val;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
 {
        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
        /* FIXME: the following conflict with IEC958 Playback Route */
@@ -1668,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
        spin_lock_irq(&ice->reg_lock);
        oval = inb(ICEMT1724(ice, RATE));
        if (ucontrol->value.enumerated.item[0] == spdif) {
+               unsigned char i2s_oval;
                outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
+               /* setting 256fs */
+               i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
+               outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X,
+                    ICEMT1724(ice, I2S_FORMAT));
        } else {
                rate = rates[ucontrol->value.integer.value[0] % 15];
                if (rate <= get_max_rate(ice)) {
@@ -1695,7 +1698,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Internal Clock",
        .info = snd_vt1724_pro_internal_clock_info,
@@ -1734,7 +1737,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Rate Locking",
        .info = snd_vt1724_pro_rate_locking_info,
@@ -1773,7 +1776,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
        return change;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Rate Reset",
        .info = snd_vt1724_pro_rate_reset_info,
@@ -1892,7 +1895,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
                             digital_route_shift(idx));
 }
 
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "H/W Playback Route",
        .info = snd_vt1724_pro_route_info,
@@ -1900,7 +1903,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit
        .put = snd_vt1724_pro_route_analog_put,
 };
 
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
        .info = snd_vt1724_pro_route_info,
@@ -1936,7 +1939,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
        .name = "Multi Track Peak",
        .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -1948,9 +1951,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
  *
  */
 
-static const struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched __devinitdata;
 
-static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
        snd_vt1724_revo_cards,
        snd_vt1724_amp_cards, 
        snd_vt1724_aureon_cards,
@@ -2009,7 +2012,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
 {
        const int dev = 0xa0;           /* EEPROM device address */
        unsigned int i, size;
-       const struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (! modelname || ! *modelname) {
                ice->eeprom.subvendor = 0;
@@ -2308,7 +2311,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
        struct snd_card *card;
        struct snd_ice1712 *ice;
        int pcm_dev = 0, err;
-       const struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (dev >= SNDRV_CARDS)
                return -ENODEV;
@@ -2347,6 +2350,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
        }
        c = &no_matched;
  __found:
+       /*
+        * VT1724 has separate DMAs for the analog and the SPDIF streams while
+        * ICE1712 has only one for both (mixed up).
+        *
+        * Confusingly the analog PCM is named "professional" here because it
+        * was called so in ice1712 driver, and vt1724 driver is derived from
+        * ice1712 driver.
+        */
 
        if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
                snd_card_free(card);
index d88172fa95da5f9f539871e509afba47e72a2797..3d8e74e493d797a65f27cd3c174ab1c5d0ae2935 100644 (file)
@@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
        snd_akm4xxx_reset(ak, 0);
 }
 
-static const struct snd_akm4xxx akm_juli_dac __devinitdata = {
+static struct snd_akm4xxx akm_juli_dac __devinitdata = {
        .type = SND_AK4358,
        .num_dacs = 2,
        .ops = {
@@ -138,7 +138,16 @@ static const struct snd_akm4xxx akm_juli_dac __devinitdata = {
 
 static int __devinit juli_add_controls(struct snd_ice1712 *ice)
 {
-       return snd_ice1712_akm4xxx_build_controls(ice);
+       int err;
+       err = snd_ice1712_akm4xxx_build_controls(ice);
+       if (err < 0)
+               return err;
+       /* only capture SPDIF over AK4114 */
+       err = snd_ak4114_build(ice->spec.juli.ak4114, NULL,
+                              ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
+       if (err < 0)
+               return err;
+       return 0;
 }
 
 /*
@@ -160,13 +169,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
        int err;
        struct snd_akm4xxx *ak;
 
-#if 0
-       for (err = 0; err < 0x20; err++)
-               juli_ak4114_read(ice, err);
-       juli_ak4114_write(ice, 0, 0x0f);
-       juli_ak4114_read(ice, 0);
-       juli_ak4114_read(ice, 1);
-#endif
        err = snd_ak4114_create(ice->card,
                                juli_ak4114_read,
                                juli_ak4114_write,
@@ -206,7 +208,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
  * hence the driver needs to sets up it properly.
  */
 
-static const unsigned char juli_eeprom[] __devinitdata = {
+static unsigned char juli_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x20,  /* clock 512, mpu401, 1xADC, 1xDACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xf8,  /* vol, 96k, 24bit, 192k */
@@ -223,7 +225,7 @@ static const unsigned char juli_eeprom[] __devinitdata = {
 };
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_JULI,
                .name = "ESI Juli@",
index 1b9294f8bce3543423bc84d338c7f70c2725ac88..d9f8534fd92ee527f12e337fd0cca53ed7a77004 100644 (file)
@@ -5,6 +5,6 @@
 
 #define VT1724_SUBDEVICE_JULI          0x31305345      /* Juli@ */
 
-extern const struct snd_ice1712_card_info  snd_vt1724_juli_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_juli_cards[];
 
 #endif /* __SOUND_JULI_H */
index 0751718f4d7b18a5420f79484ae558aa9bc56677..40a9098af777c3b0c387069276648a6178693443 100644 (file)
@@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = {
 #define WM_VOL_MAX     (sizeof(wm_vol) - 1)
 #define WM_VOL_MUTE    0x8000
 
-static const struct snd_akm4xxx akm_phase22 __devinitdata = {
+static struct snd_akm4xxx akm_phase22 __devinitdata = {
        .type = SND_AK4524,
        .num_dacs = 2,
        .num_adcs = 2,
 };
 
-static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
        .caddr =        2,
        .cif =          1,
        .data_mask =    1 << 4,
@@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
        return 0;
 }
 
-static const unsigned char phase22_eeprom[] __devinitdata = {
+static unsigned char phase22_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x00,  /* 1xADC, 1xDACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xf8,  /* vol, 96k, 24bit */
@@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = {
        [ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static const unsigned char phase28_eeprom[] __devinitdata = {
+static unsigned char phase28_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x0b,  /* clock 512, spdif-in/ADC, 4DACs */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xfc,  /* vol, 96k, 24bit, 192k */
@@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 
-static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
@@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
        }
 };
 
-static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "PCM Playback Switch",
@@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
        return 0;
 }
 
-const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_PHASE22,
                .name = "Terratec PHASE 22",
index ad379a99bf92bd67c0a86d278421140801d37382..13e841b554887a8c6b8ae9eac8ff3d17c762087c 100644 (file)
@@ -31,7 +31,7 @@
 #define VT1724_SUBDEVICE_PHASE28       0x3b154911
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
 
 /* PHASE28 GPIO bits */
 #define PHASE28_SPI_MISO       (1 << 21)
index 9552497f0765a6f13a8ebd952f6330feb7af3956..01c69453ddebd579b930810efc09c8fa3b66e1f0 100644 (file)
@@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
  * mixers
  */
 
-static const struct snd_kcontrol_new pontis_controls[] __devinitdata = {
+static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
  * hence the driver needs to sets up it properly.
  */
 
-static const unsigned char pontis_eeprom[] __devinitdata = {
+static unsigned char pontis_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x08,  /* clock 256, mpu401, spdif-in/ADC, 1DAC */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xf8,  /* vol, 96k, 24bit, 192k */
@@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = {
 };
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
        {
                .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
                .name = "Pontis MS300",
index 1a418255c19ea82eeadd7f7d4cb09af274d452f5..d0d1378b935c5d2691ad8700a22f29f8145e84c5 100644 (file)
@@ -28,6 +28,6 @@
 
 #define VT1720_SUBDEVICE_PONTIS_MS300  0x00020002      /* a dummy id for MS300 */
 
-extern const struct snd_ice1712_card_info  snd_vt1720_pontis_cards[];
+extern struct snd_ice1712_card_info  snd_vt1720_pontis_cards[];
 
 #endif /* __SOUND_PONTIS_H */
index 31cc66eb9f8fa9ccd6bc9bad39794ac329dd1686..f03c02c0774335c897eda9dd1f65753a8d64940b 100644 (file)
@@ -2,6 +2,37 @@
  *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
  *
  *   Lowlevel functions for AudioTrak Prodigy 192 cards
+ *   Supported IEC958 input from optional MI/ODI/O add-on card.
+ *
+ *   Specifics (SW, HW):
+ *   -------------------
+ *     * 49.5MHz crystal
+ *     * SPDIF-OUT on the card:
+ *       - coax (through isolation transformer)/toslink supplied by
+ *          74HC04 gates - 3 in parallel
+ *       - output switched between on-board CD drive dig-out connector
+ *          and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
+ *          by GPIO20 (0 = CD dig-out, 1 = SPDTX)
+ *     * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
+ *
+ *     * MI/ODI/O card: AK4114 based, used for iec958 input only
+ *             - toslink input -> RX0
+ *             - coax input -> RX1
+ *             - 4wire protocol:
+ *                     AK4114          ICE1724
+ *                     ------------------------------
+ *                     CDTO (pin 32) -- GPIO11 pin 86
+ *                     CDTI (pin 33) -- GPIO10 pin 77
+ *                     CCLK (pin 34) -- GPIO9 pin 76
+ *                     CSN  (pin 35) -- GPIO8 pin 75
+ *             - output data Mode 7 (24bit, I2S, slave)
+ *             - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
+ *               outputs master clock to SPMCLKIN of ice1724.
+ *               Experimentally I found out that only a combination of
+ *               OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
+ *               VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
+ *               sampling rate. That means the the FPGA doubles the
+ *               MCK01 rate.
  *
  *     Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
  *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
@@ -356,6 +387,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
        return 0;
 }
 #endif
+static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_info *uinfo)
+{
+       static char *texts[2] = { "Line In", "Mic" };
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+       uinfo->count = 1;
+       uinfo->value.enumerated.items = 2;
+
+       if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+               uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+       strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+
+        return 0;
+}
+
+
+static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+       unsigned char val;
+               
+       val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+       ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
+       return 0;
+}
+
+static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+       unsigned char new, old;
+       int change;
+       old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+       new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
+       change = (new != old);
+       if (change)
+               stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
+       return change;
+}
 
 static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
@@ -364,7 +436,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
  * mixers
  */
 
-static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
@@ -406,7 +478,7 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
        },
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "ADC Switch",
+               .name = "ADC Capture Switch",
                .count = 1,
                .info = stac9460_adc_mute_info,
                .get = stac9460_adc_mute_get,
@@ -417,13 +489,21 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
                           SNDRV_CTL_ELEM_ACCESS_TLV_READ),
-               .name = "ADC Volume",
+               .name = "ADC Capture Volume",
                .count = 1,
                .info = stac9460_adc_vol_info,
                .get = stac9460_adc_vol_get,
                .put = stac9460_adc_vol_put,
                .tlv = { .p = db_scale_adc }
        },
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Analog Capture Input",
+               .info = stac9460_mic_sw_info,
+               .get = stac9460_mic_sw_get,
+               .put = stac9460_mic_sw_put,
+
+       },
 #if 0
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -456,19 +536,261 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
 #endif
 };
 
+
+/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
+/* CDTO (pin 32) -- GPIO11 pin 86
+ * CDTI (pin 33) -- GPIO10 pin 77
+ * CCLK (pin 34) -- GPIO9 pin 76
+ * CSN  (pin 35) -- GPIO8 pin 75
+ */
+#define AK4114_ADDR    0x00 /* C1-C0: Chip Address
+                             * (According to datasheet fixed to “00”)
+                             */
+
+/*
+ * 4wire ak4114 protocol - writing data
+ */
+static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
+                      unsigned int data, int idx)
+{
+       for (; idx >= 0; idx--) {
+               /* drop clock */
+               gpio &= ~VT1724_PRODIGY192_CCLK;
+               snd_ice1712_gpio_write(ice, gpio);
+               udelay(1);
+               /* set data */
+               if (data & (1 << idx))
+                       gpio |= VT1724_PRODIGY192_CDOUT;
+               else
+                       gpio &= ~VT1724_PRODIGY192_CDOUT;
+               snd_ice1712_gpio_write(ice, gpio);
+               udelay(1);
+               /* raise clock */
+               gpio |= VT1724_PRODIGY192_CCLK;
+               snd_ice1712_gpio_write(ice, gpio);
+               udelay(1);
+       }
+}
+
+/*
+ * 4wire ak4114 protocol - reading data
+ */
+static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
+                              int idx)
+{
+       unsigned char data = 0;
+
+       for (; idx >= 0; idx--) {
+               /* drop clock */
+               gpio &= ~VT1724_PRODIGY192_CCLK;
+               snd_ice1712_gpio_write(ice, gpio);
+               udelay(1);
+               /* read data */
+               if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN)
+                       data |= (1 << idx);
+               udelay(1);
+               /* raise clock */
+               gpio |= VT1724_PRODIGY192_CCLK;
+               snd_ice1712_gpio_write(ice, gpio);
+               udelay(1);
+       }
+       return data;
+}
+/*
+ * 4wire ak4114 protocol - starting sequence
+ */
+static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice)
+{
+       unsigned int tmp;
+
+       snd_ice1712_save_gpio_status(ice);
+       tmp = snd_ice1712_gpio_read(ice);
+
+       tmp |= VT1724_PRODIGY192_CCLK; /* high at init */
+       tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */
+       snd_ice1712_gpio_write(ice, tmp);
+       udelay(1);
+       return tmp;
+}
+
+/*
+ * 4wire ak4114 protocol - final sequence
+ */
+static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
+{
+       tmp |= VT1724_PRODIGY192_CS; /* raise chip select */
+       snd_ice1712_gpio_write(ice, tmp);
+       udelay(1);
+       snd_ice1712_restore_gpio_status(ice);
+}
+
+/*
+ * Write data to addr register of ak4114
+ */
+static void prodigy192_ak4114_write(void *private_data, unsigned char addr,
+                              unsigned char data)
+{
+       struct snd_ice1712 *ice = private_data;
+       unsigned int tmp, addrdata;
+       tmp = prodigy192_4wire_start(ice);
+       addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
+       addrdata = (addrdata << 8) | data;
+       write_data(ice, tmp, addrdata, 15);
+       prodigy192_4wire_finish(ice, tmp);
+}
+
+/*
+ * Read data from addr register of ak4114
+ */
+static unsigned char prodigy192_ak4114_read(void *private_data,
+                                           unsigned char addr)
+{
+       struct snd_ice1712 *ice = private_data;
+       unsigned int tmp;
+       unsigned char data;
+
+       tmp = prodigy192_4wire_start(ice);
+       write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
+       data = read_data(ice, tmp, 7);
+       prodigy192_4wire_finish(ice, tmp);
+       return data;
+}
+
+
+static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
+                               struct snd_ctl_elem_info *uinfo)
+{
+       static char *texts[2] = { "Toslink", "Coax" };
+
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+       uinfo->count = 1;
+       uinfo->value.enumerated.items = 2;
+       if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+               uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+       strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+        return 0;
+}
+
+
+static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+       unsigned char val;
+               
+       val = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
+       /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
+        * AK4114_IPS0 bit = 1 -> RX1 = Coax
+        */
+       ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0;
+       return 0;
+}
+
+static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+       unsigned char new, old, itemvalue;
+       int change;
+
+       old = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
+       /* AK4114_IPS0 could be any bit */
+       itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00;
+
+       new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0);
+       change = (new != old);
+       if (change)
+               prodigy192_ak4114_write(ice, AK4114_REG_IO1, new);
+       return change;
+}
+
+
+static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "MIODIO IEC958 Capture Input",
+               .info = ak4114_input_sw_info,
+               .get = ak4114_input_sw_get,
+               .put = ak4114_input_sw_put,
+
+       }
+};
+
+
+static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
+{
+       static const unsigned char ak4114_init_vals[] = {
+               AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
+               /* ice1724 expects I2S and provides clock,
+                * DEM0 disables the deemphasis filter
+                */
+               AK4114_DIF_I24I2S | AK4114_DEM0 ,
+               AK4114_TX1E,
+               AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */
+               0,
+               0
+       };
+       static const unsigned char ak4114_init_txcsb[] = {
+               0x41, 0x02, 0x2c, 0x00, 0x00
+       };
+
+       return snd_ak4114_create(ice->card,
+                                prodigy192_ak4114_read,
+                                prodigy192_ak4114_write,
+                                ak4114_init_vals, ak4114_init_txcsb,
+                                ice, &ice->spec.prodigy192.ak4114);
+}
+
 static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
 {
        unsigned int i;
        int err;
 
        for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
-               err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice));
+               err = snd_ctl_add(ice->card,
+                                 snd_ctl_new1(&stac_controls[i], ice));
+               if (err < 0)
+                       return err;
+       }
+       if (ice->spec.prodigy192.ak4114) {
+               /* ak4114 is connected */
+               for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
+                       err = snd_ctl_add(ice->card,
+                                         snd_ctl_new1(&ak4114_controls[i],
+                                                      ice));
+                       if (err < 0)
+                               return err;
+               }
+               err = snd_ak4114_build(ice->spec.prodigy192.ak4114,
+                               NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
+                               ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
                if (err < 0)
                        return err;
        }
        return 0;
 }
 
+/*
+ * check for presence of MI/ODI/O add-on card with digital inputs
+ */
+static int prodigy192_miodio_exists(struct snd_ice1712 *ice)
+{
+
+       unsigned char orig_value;
+       const unsigned char test_data = 0xd1;   /* random value */
+       unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */
+       int exists = 0;
+
+       orig_value = prodigy192_ak4114_read(ice, addr);
+       prodigy192_ak4114_write(ice, addr, test_data);
+       if (prodigy192_ak4114_read(ice, addr) == test_data) {
+               /* ak4114 seems to communicate, apparently exists */
+               /* writing back original value */
+               prodigy192_ak4114_write(ice, addr, orig_value);
+               exists = 1;
+       }
+       return exists;
+}
 
 /*
  * initialize the chip
@@ -487,16 +809,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
                (unsigned short)-1
        };
        const unsigned short *p;
+       int err = 0;
 
        /* prodigy 192 */
        ice->num_total_dacs = 6;
        ice->num_total_adcs = 2;
+       ice->vt1720 = 0;  /* ice1724, e.g. 23 GPIOs */
        
        /* initialize codec */
        p = stac_inits_prodigy;
        for (; *p != (unsigned short)-1; p += 2)
                stac9460_put(ice, p[0], p[1]);
 
+       /* MI/ODI/O add on card with AK4114 */
+       if (prodigy192_miodio_exists(ice)) {
+               err = prodigy192_ak4114_init(ice);
+               /* from this moment if err = 0 then
+                * ice->spec.prodigy192.ak4114 should not be null
+                */
+               snd_printdd("AK4114 initialized with status %d\n", err);
+       } else
+               snd_printdd("AK4114 not found\n");
+       if (err < 0)
+               return err;
+
        return 0;
 }
 
@@ -506,25 +842,31 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
  * hence the driver needs to sets up it properly.
  */
 
-static const unsigned char prodigy71_eeprom[] __devinitdata = {
-       [ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401, spdif-in/ADC, 4DACs */
+static unsigned char prodigy71_eeprom[] __devinitdata = {
+       [ICE_EEP2_SYSCONF]     = 0x6a,  /* 49MHz crystal, mpu401,
+                                        * spdif-in+ 1 stereo ADC,
+                                        * 3 stereo DACs
+                                        */
        [ICE_EEP2_ACLINK]      = 0x80,  /* I2S */
        [ICE_EEP2_I2S]         = 0xf8,  /* vol, 96k, 24bit, 192k */
        [ICE_EEP2_SPDIF]       = 0xc3,  /* out-en, out-int, spdif-in */
        [ICE_EEP2_GPIO_DIR]    = 0xff,
-       [ICE_EEP2_GPIO_DIR1]   = 0xff,
+       [ICE_EEP2_GPIO_DIR1]   = ~(VT1724_PRODIGY192_CDIN >> 8) ,
        [ICE_EEP2_GPIO_DIR2]   = 0xbf,
        [ICE_EEP2_GPIO_MASK]   = 0x00,
        [ICE_EEP2_GPIO_MASK1]  = 0x00,
        [ICE_EEP2_GPIO_MASK2]  = 0x00,
        [ICE_EEP2_GPIO_STATE]  = 0x00,
        [ICE_EEP2_GPIO_STATE1] = 0x00,
-       [ICE_EEP2_GPIO_STATE2] = 0x00,
+       [ICE_EEP2_GPIO_STATE2] = 0x10,  /* GPIO20: 0 = CD drive dig. input
+                                        * passthrough,
+                                        * 1 = SPDIF-OUT from ice1724
+                                        */
 };
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
                .name = "Audiotrak Prodigy 192",
index 2fa2e62b9e047cea85254f97519aee75c4f5c105..16a53b459c728a6833744ad704e93dc9bc8a3ef9 100644 (file)
@@ -5,7 +5,15 @@
 #define PRODIGY192_STAC9460_ADDR       0x54
 
 #define VT1724_SUBDEVICE_PRODIGY192VE   0x34495345     /* PRODIGY 192 VE */
+/*
+ *  AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with
+ *  AK4114 (SPDIF-IN)
+ */
+#define VT1724_PRODIGY192_CS   (1 << 8)        /* GPIO8, pin 75 */
+#define VT1724_PRODIGY192_CCLK (1 << 9)        /* GPIO9, pin 76 */
+#define VT1724_PRODIGY192_CDOUT        (1 << 10)       /* GPIO10, pin 77 */
+#define VT1724_PRODIGY192_CDIN (1 << 11)       /* GPIO11, pin 86 */
 
-extern const struct snd_ice1712_card_info  snd_vt1724_prodigy192_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_prodigy192_cards[];
 
 #endif /* __SOUND_PRODIGY192_H */
index 025a7e8497c30cbb44a847a722a04bd264a33213..690ceb34064444575578a982a04e1b51d428f9ed 100644 (file)
@@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
        },
 };
 
-static const struct snd_akm4xxx akm_revo_front __devinitdata = {
+static struct snd_akm4xxx akm_revo_front __devinitdata = {
        .type = SND_AK4381,
        .num_dacs = 2,
        .ops = {
@@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = {
        .dac_info = revo71_front,
 };
 
-static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
        .caddr = 1,
        .cif = 0,
        .data_mask = VT1724_REVO_CDOUT,
@@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_revo_surround __devinitdata = {
+static struct snd_akm4xxx akm_revo_surround __devinitdata = {
        .type = SND_AK4355,
        .idx_offset = 1,
        .num_dacs = 6,
@@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = {
        .dac_info = revo71_surround,
 };
 
-static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
        .caddr = 3,
        .cif = 0,
        .data_mask = VT1724_REVO_CDOUT,
@@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_revo51 __devinitdata = {
+static struct snd_akm4xxx akm_revo51 __devinitdata = {
        .type = SND_AK4358,
        .num_dacs = 6,
        .ops = {
@@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = {
        .dac_info = revo51_dac,
 };
 
-static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
        .caddr = 2,
        .cif = 0,
        .data_mask = VT1724_REVO_CDOUT,
@@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_revo51_adc __devinitdata = {
+static struct snd_akm4xxx akm_revo51_adc __devinitdata = {
        .type = SND_AK5365,
        .num_adcs = 2,
        .adc_info = revo51_adc,
 };
 
-static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
        .caddr = 2,
        .cif = 0,
        .data_mask = VT1724_REVO_CDOUT,
@@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
        AK_DAC("PCM Playback Volume", 2)
 };
 
-static const struct snd_akm4xxx akm_ap192 __devinitdata = {
+static struct snd_akm4xxx akm_ap192 __devinitdata = {
        .type = SND_AK4358,
        .num_dacs = 2,
        .ops = {
@@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = {
        .dac_info = ap192_dac,
 };
 
-static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
        .caddr = 2,
        .cif = 0,
        .data_mask = VT1724_REVO_CDOUT,
@@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
        return data;
 }
 
-static unsigned char ap192_4wire_start(struct snd_ice1712 *ice)
+static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
 {
        unsigned int tmp;
 
@@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
        return data;
 }
 
-static int ap192_ak4114_init(struct snd_ice1712 *ice)
+static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice)
 {
        static const unsigned char ak4114_init_vals[] = {
                AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
@@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)
 }
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
        {
                .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
                .name = "M Audio Revolution-7.1",
index 2a24488fad805653d99195d352d3b48442d03dd8..a3ba425911cc3aaa367b77438ebca2d21e2162a3 100644 (file)
@@ -34,7 +34,7 @@
 #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
 
 
 /*
index 72b060d63c29cc83307f468bd85335d128f809d5..239524158fe7c1837565366dec27b1cdfaa98e4d 100644 (file)
@@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
 
 /* EEPROM image */
 
-static const unsigned char k8x800_eeprom[] __devinitdata = {
+static unsigned char k8x800_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x01,  /* clock 256, 1ADC, 2DACs */
        [ICE_EEP2_ACLINK]      = 0x02,  /* ACLINK, packed */
        [ICE_EEP2_I2S]         = 0x00,  /* - */
@@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = {
        [ICE_EEP2_GPIO_STATE2] = 0x00,  /* - */
 };
 
-static const unsigned char sn25p_eeprom[] __devinitdata = {
+static unsigned char sn25p_eeprom[] __devinitdata = {
        [ICE_EEP2_SYSCONF]     = 0x01,  /* clock 256, 1ADC, 2DACs */
        [ICE_EEP2_ACLINK]      = 0x02,  /* ACLINK, packed */
        [ICE_EEP2_I2S]         = 0x00,  /* - */
@@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = {
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
        {
                .subvendor = VT1720_SUBDEVICE_K8X800,
                .name = "Albatron K8X800 Pro II",
index 70af3ad64a5d3d36b5577cc2fd0ca4a2240ff6e8..0b1b0ee1bea7aba566eec6206793009a44dd718c 100644 (file)
@@ -36,6 +36,6 @@
 #define VT1720_SUBDEVICE_9CJS          0x0f272327
 #define VT1720_SUBDEVICE_SN25P         0x97123650
 
-extern const struct snd_ice1712_card_info  snd_vt1720_mobo_cards[];
+extern struct snd_ice1712_card_info  snd_vt1720_mobo_cards[];
 
 #endif /* __SOUND_VT1720_MOBO_H */
index 4a706b16a0b9ba683501a9c92c0946d68182c740..04e535c8542bc1b4c832e7a3845a359de0e25cb3 100644 (file)
@@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
 /*
  * Control tabs
  */
-static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
index 7cf2dcb9d8d4b99010204bf643f89952b9ec6dd7..202f720b34b9b4116848b9d8888912657d348dcd 100644 (file)
@@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci)
                return -EIO;
        }
        pci_set_master(pci);
+       snd_intel8x0_chip_init(chip, 0);
        if (request_irq(pci->irq, snd_intel8x0_interrupt,
                        IRQF_SHARED, card->shortname, chip)) {
                printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
@@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci)
        }
        chip->irq = pci->irq;
        synchronize_irq(chip->irq);
-       snd_intel8x0_chip_init(chip, 0);
 
        /* re-initialize mixer stuff */
        if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
@@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
                ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
        chip->int_sta_mask = int_sta_masks;
 
-       /* request irq after initializaing int_sta_mask, etc */
-       if (request_irq(pci->irq, snd_intel8x0_interrupt,
-                       IRQF_SHARED, card->shortname, chip)) {
-               snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
-               snd_intel8x0_free(chip);
-               return -EBUSY;
-       }
-       chip->irq = pci->irq;
        pci_set_master(pci);
-       synchronize_irq(chip->irq);
 
        switch(chip->device_type) {
        case DEVICE_INTEL_ICH4:
@@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
                return err;
        }
 
+       /* request irq after initializaing int_sta_mask, etc */
+       if (request_irq(pci->irq, snd_intel8x0_interrupt,
+                       IRQF_SHARED, card->shortname, chip)) {
+               snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+               snd_intel8x0_free(chip);
+               return -EBUSY;
+       }
+       chip->irq = pci->irq;
+
        if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
                snd_intel8x0_free(chip);
                return err;
index 21d0899ac382cedf13cfd3919be969656bec0806..5338243fb0353937c079885d1de4d28ba5c210a3 100644 (file)
@@ -264,9 +264,7 @@ enum MonitorModeSelector {
 #define COMMAND_ACK_DELAY   13         // number of RTC ticks to wait for an acknowledgement
                                        //    from the card after sending a command.
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
 #include "korg1212-firmware.h"
 static const struct firmware static_dsp_code = {
        .data = (u8 *)dspCode,
@@ -418,6 +416,9 @@ struct snd_korg1212 {
 MODULE_DESCRIPTION("korg1212");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("korg/k1212.dsp");
+#endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;         /* ID for this card */
@@ -2342,26 +2343,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
         korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
                offsetof(struct KorgSharedBuffer, AdatTimeCode);
 
+#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+       dsp_code = &static_dsp_code;
+#else
        err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
        if (err < 0) {
                release_firmware(dsp_code);
-#ifdef FIRMWARE_IN_THE_KERNEL
-               dsp_code = &static_dsp_code;
-#else
                snd_printk(KERN_ERR "firmware not available\n");
                snd_korg1212_free(korg1212);
                return err;
-#endif
        }
+#endif
 
        if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
                                dsp_code->size, &korg1212->dma_dsp) < 0) {
                snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
                 snd_korg1212_free(korg1212);
-#ifdef FIRMWARE_IN_THE_KERNEL
-               if (dsp_code != &static_dsp_code)
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+               release_firmware(dsp_code);
 #endif
-                       release_firmware(dsp_code);
                 return -ENOMEM;
         }
 
@@ -2371,10 +2371,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
 
        memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
 
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (dsp_code != &static_dsp_code)
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+       release_firmware(dsp_code);
 #endif
-               release_firmware(dsp_code);
 
        rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
 
index 4526904e3f86df587fe37eb1ad9783c64c3bef25..8a5ff1cb53624a7af375202fde52073d733d21cc 100644 (file)
@@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
                "{ESS,Allegro PCI},"
                "{ESS,Allegro-1 PCI},"
                "{ESS,Canyon3D-2/LE PCI}}");
+#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");
+MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");
+#endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
@@ -2101,9 +2105,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
 }
 
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
 
 /*
  * DSP Code images
@@ -2242,7 +2244,7 @@ static const struct firmware assp_minisrc = {
        .size = sizeof assp_minisrc_image
 };
 
-#endif /* FIRMWARE_IN_THE_KERNEL */
+#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
 
 #ifdef __LITTLE_ENDIAN
 static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
@@ -2257,6 +2259,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw)
 }
 #endif
 
+#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
+
 
 /*
  * initialize ASSP
@@ -2550,14 +2554,10 @@ static int snd_m3_free(struct snd_m3 *chip)
        if (chip->iobase)
                pci_release_regions(chip->pci);
 
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (chip->assp_kernel_image != &assp_kernel)
+#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+       release_firmware(chip->assp_kernel_image);
+       release_firmware(chip->assp_minisrc_image);
 #endif
-               release_firmware(chip->assp_kernel_image);
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (chip->assp_minisrc_image != &assp_minisrc)
-#endif
-               release_firmware(chip->assp_minisrc_image);
 
        pci_disable_device(chip->pci);
        kfree(chip);
@@ -2747,29 +2747,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
                return -ENOMEM;
        }
 
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+       chip->assp_kernel_image = &assp_kernel;
+#else
        err = request_firmware(&chip->assp_kernel_image,
                               "ess/maestro3_assp_kernel.fw", &pci->dev);
        if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-               chip->assp_kernel_image = &assp_kernel;
-#else
                snd_m3_free(chip);
                return err;
-#endif
        } else
                snd_m3_convert_from_le(chip->assp_kernel_image);
+#endif
 
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+       chip->assp_minisrc_image = &assp_minisrc;
+#else
        err = request_firmware(&chip->assp_minisrc_image,
                               "ess/maestro3_assp_minisrc.fw", &pci->dev);
        if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-               chip->assp_minisrc_image = &assp_minisrc;
-#else
                snd_m3_free(chip);
                return err;
-#endif
        } else
                snd_m3_convert_from_le(chip->assp_minisrc_image);
+#endif
 
        if ((err = pci_request_regions(pci, card->driver)) < 0) {
                snd_m3_free(chip);
index ca05075c67c62f35451c58c495c5f50d3738a0d0..1d9232d2db342c0569f468f1df036e9b2e5e2da7 100644 (file)
@@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
        return 0;
 }
 
+MODULE_FIRMWARE("mixart/miXart8.xlx");
+MODULE_FIRMWARE("mixart/miXart8.elf");
+MODULE_FIRMWARE("mixart/miXart8AES.xlx");
 
 #else /* old style firmware loading */
 
index d97413484ae9f80ba547f57ea0e932814524ea6d..f7f6a687f033d16dab9b8d0b4534f79ba68e7832 100644 (file)
@@ -638,22 +638,22 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
 static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
 {
        struct pcxhr_stream *stream;
-       struct list_head *pos;
        struct snd_pcm_substream *s;
-       int i;
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                snd_printdd("SNDRV_PCM_TRIGGER_START\n");
-               i = 0;
-               snd_pcm_group_for_each(pos, subs) {
-                       s = snd_pcm_group_substream_entry(pos);
-                       stream = s->runtime->private_data;
-                       stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
-                       snd_pcm_trigger_done(s, subs);
-                       i++;
-               }
-               if (i==1) {
+               if (snd_pcm_stream_linked(subs)) {
+                       struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+                       snd_pcm_group_for_each_entry(s, subs) {
+                               stream = s->runtime->private_data;
+                               stream->status =
+                                       PCXHR_STREAM_STATUS_SCHEDULE_RUN;
+                               snd_pcm_trigger_done(s, subs);
+                       }
+                       tasklet_hi_schedule(&chip->mgr->trigger_taskq);
+               } else {
+                       stream = subs->runtime->private_data;
                        snd_printdd("Only one Substream %c %d\n",
                                    stream->pipe->is_capture ? 'C' : 'P',
                                    stream->pipe->first_audio);
@@ -665,15 +665,11 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
                        if (pcxhr_set_stream_state(stream))
                                return -EINVAL;
                        stream->status = PCXHR_STREAM_STATUS_RUNNING;
-               } else {
-                       struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
-                       tasklet_hi_schedule(&chip->mgr->trigger_taskq);
                }
                break;
        case SNDRV_PCM_TRIGGER_STOP:
                snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
-               snd_pcm_group_for_each(pos, subs) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, subs) {
                        stream = s->runtime->private_data;
                        stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;
                        if (pcxhr_set_stream_state(stream))
index 369c19fea985f11af6c108ac1e9aa3e6668c0485..d55d8bc90eee96f0302f37e9cda6801010ccd5ae 100644 (file)
@@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
        return 0;
 }
 
+MODULE_FIRMWARE("pcxhr/xi_1_882.dat");
+MODULE_FIRMWARE("pcxhr/xc_1_882.dat");
+MODULE_FIRMWARE("pcxhr/e321_512.e56");
+MODULE_FIRMWARE("pcxhr/b321_512.b56");
+MODULE_FIRMWARE("pcxhr/d321_512.d56");
+
 #else /* old style firmware loading */
 
 /* pcxhr hwdep interface id string */
index 952625dead58ef56973f48fbbe122cc63fd8a58e..8e5410483e67a0f851ea99c9209589739a143282 100644 (file)
@@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");
 MODULE_DESCRIPTION("riptide");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");
+MODULE_FIRMWARE("riptide.hex");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
index 6bb7ac650ec42dde1fc8dfb97ff304881bee976c..618653e22561ba3a208afa55138201549c224334 100644 (file)
@@ -1078,12 +1078,10 @@ static int
 snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct rme32 *rme32 = snd_pcm_substream_chip(substream);
-       struct list_head *pos;
        struct snd_pcm_substream *s;
 
        spin_lock(&rme32->lock);
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                if (s != rme32->playback_substream &&
                    s != rme32->capture_substream)
                        continue;
@@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        
        /* prefill playback buffer */
        if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) {
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == rme32->playback_substream) {
                                s->ops->ack(s);
                                break;
index 89b3c7ff5037ad85586d6a48db973a7532b158fe..3b3ef657f73eb86e323e69f423bcec58eb884f56 100644 (file)
@@ -60,6 +60,12 @@ MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
                "{RME HDSP-9652},"
                "{RME HDSP-9632}}");
+#ifdef HDSP_FW_LOADER
+MODULE_FIRMWARE("multiface_firmware.bin");
+MODULE_FIRMWARE("multiface_firmware_rev11.bin");
+MODULE_FIRMWARE("digiface_firmware.bin");
+MODULE_FIRMWARE("digiface_firmware_rev11.bin");
+#endif
 
 #define HDSP_MAX_CHANNELS        26
 #define HDSP_MAX_DS_CHANNELS     14
@@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
 #define HDSP_Frequency128KHz   (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
 #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
 #define HDSP_Frequency192KHz   (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
+/* RME says n = 104857600000000, but in the windows MADI driver, I see:
+       return 104857600000000 / rate; // 100 MHz
+       return 110100480000000 / rate; // 105 MHz
+*/
+#define DDS_NUMERATOR 104857600000000ULL;  /*  =  2^20 * 10^8 */
 
 #define hdsp_encode_latency(x)       (((x)<<1) & HDSP_LatencyMask)
 #define hdsp_decode_latency(x)       (((x) & HDSP_LatencyMask)>>1)
@@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
        else if (rate >= 56000)
                rate /= 2;
 
-       /* RME says n = 104857600000000, but in the windows MADI driver, I see:
-//     return 104857600000000 / rate; // 100 MHz
-       return 110100480000000 / rate; // 105 MHz
-        */        
-       n = 104857600000000ULL;  /*  =  2^20 * 10^8 */
+       n = DDS_NUMERATOR;
        div64_32(&n, rate, &r);
        /* n should be less than 2^32 for being written to FREQ register */
        snd_assert((n >> 32) == 0);
@@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
        return 0;
 }
 
+#define HDSP_DDS_OFFSET(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdsp_info_dds_offset, \
+  .get = snd_hdsp_get_dds_offset, \
+  .put = snd_hdsp_put_dds_offset \
+}
+
+static int hdsp_dds_offset(struct hdsp *hdsp)
+{
+       u64 n;
+       u32 r;
+       unsigned int dds_value = hdsp->dds_value;
+       int system_sample_rate = hdsp->system_sample_rate;
+
+       n = DDS_NUMERATOR;
+       /*
+        * dds_value = n / rate
+        * rate = n / dds_value
+        */
+       div64_32(&n, dds_value, &r);
+       if (system_sample_rate >= 112000)
+               n *= 4;
+       else if (system_sample_rate >= 56000)
+               n *= 2;
+       return ((int)n) - system_sample_rate;
+}
+
+static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
+{
+       int rate = hdsp->system_sample_rate + offset_hz;
+       hdsp_set_dds_value(hdsp, rate);
+       return 0;
+}
+
+static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = -5000;
+       uinfo->value.integer.max = 5000;
+       return 0;
+}
+
+static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+       
+       ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
+       return 0;
+}
+
+static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+       int change;
+       int val;
+       
+       if (!snd_hdsp_use_is_exclusive(hdsp))
+               return -EBUSY;
+       val = ucontrol->value.enumerated.item[0];
+       spin_lock_irq(&hdsp->lock);
+       if (val != hdsp_dds_offset(hdsp))
+               change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
+       else
+               change = 0;
+       spin_unlock_irq(&hdsp->lock);
+       return change;
+}
+
 static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
 HDSP_DA_GAIN("DA Gain", 0),
 HDSP_AD_GAIN("AD Gain", 0),
 HDSP_PHONE_GAIN("Phones Gain", 0),
-HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
+HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
+HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0)
 };
 
 static struct snd_kcontrol_new snd_hdsp_controls[] = {
@@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream)
        else
                runtime->status->hw_ptr = 0;
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
                struct snd_pcm_runtime *oruntime = other->runtime;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                oruntime->status->hw_ptr = runtime->status->hw_ptr;
                                break;
@@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
                other = hdsp->playback_substream;
 
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                snd_pcm_trigger_done(s, substream);
                                if (cmd == SNDRV_PCM_TRIGGER_START)
index 6e95857e4e67a4cd10f5843312cae93ed661237b..143185e7e4dc0881b6aac43eb91afe5164b2bde6 100644 (file)
@@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
 #define HDSPM_controlRegister       64
 #define HDSPM_interruptConfirmation  96
 #define HDSPM_control2Reg           256  /* not in specs ???????? */
+#define HDSPM_freqReg                256  /* for AES32 */
 #define HDSPM_midiDataOut0          352  /* just believe in old code */
 #define HDSPM_midiDataOut1          356
+#define HDSPM_eeprom_wr                     384  /* for AES32 */
 
 /* DMA enable for 64 channels, only Bit 0 is relevant */
 #define HDSPM_outputEnableBase       512  /* 512-767  input  DMA */ 
@@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
    size is the same regardless of the number of channels, and
    also the latency to use. 
    for one direction !!!
-   => need to mupltiply by 2!!
 */
-#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
+#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
 #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
 
 /* revisions >= 230 indicate AES32 card */
@@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
    56, 57, 58, 59, 60, 61, 62, 63
 };
 
-static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = {
-  0, 2, 4, 6, 8, 10, 12, 14,
-  16, 18, 20, 22, 24, 26, 28, 30,
-  32, 34, 36, 38, 40, 42, 44, 46,
-  48, 50, 52, 54, 56, 58, 60, 62,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = {
-  0,   4,  8, 12, 16, 20, 24,  28,  
-  32, 36, 40, 44, 48, 52, 56,  60
-  -1, -1, -1, -1, -1, -1, -1, -1,  
-  -1, -1, -1, -1, -1, -1, -1, -1,  
-  -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1
-};
-
 
 static struct pci_device_id snd_hdspm_ids[] __devinitdata = {
        {
@@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
        return 0;
 }
 
+static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
+{
+       u64 n;
+       u32 r;
+       
+       if (rate >= 112000)
+               rate /= 4;
+       else if (rate >= 56000)
+               rate /= 2;
+
+       /* RME says n = 104857600000000, but in the windows MADI driver, I see:
+//     return 104857600000000 / rate; // 100 MHz
+       return 110100480000000 / rate; // 105 MHz
+        */        
+       //n = 104857600000000ULL;  /*  =  2^20 * 10^8 */
+       n = 110100480000000ULL;    /* Value checked for AES32 and MADI */
+       div64_32(&n, rate, &r);
+       /* n should be less than 2^32 for being written to FREQ register */
+       snd_assert((n >> 32) == 0);
+       hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
+}
 
 /* dummy set rate lets see what happens */
 static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
@@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
        hdspm->control_register |= rate_bits;
        hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
 
-       if (rate > 96000 /* 64000*/)
-               hdspm->channel_map = channel_map_madi_qs;
-       else if (rate > 48000)
-               hdspm->channel_map = channel_map_madi_ds;
-       else 
-               hdspm->channel_map = channel_map_madi_ss;
+       /* For AES32, need to set DDS value in FREQ register
+          For MADI, also apparently */
+       hdspm_set_dds_value(hdspm, rate);
+       
+       if (hdspm->is_aes32 && rate != current_rate)
+               hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
+       
+       /* For AES32 and for MADI (at least rev 204), channel_map needs to
+        * always be channel_map_madi_ss, whatever the sample rate */
+       hdspm->channel_map = channel_map_madi_ss;
 
        hdspm->system_sample_rate = rate;
 
@@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
                    hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
                    hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
        snd_iprintf(buffer,
-                   "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
-                   hdspm->control_register, hdspm->control2_register,
+                   "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
+                   hdspm->control_register,
                    status, status2, timecode);
 
        snd_iprintf(buffer, "--- Settings ---\n");
@@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
 
        hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
 
+        if (!hdspm->is_aes32) {
+               /* No control2 register for AES32 */
 #ifdef SNDRV_BIG_ENDIAN
-       hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
+               hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
 #else
-       hdspm->control2_register = 0;
+               hdspm->control2_register = 0;
 #endif
 
-       hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
+               hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
+       }
        hdspm_compute_period_size(hdspm);
 
        /* silence everything */
@@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream)
        else
                runtime->status->hw_ptr = 0;
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
                struct snd_pcm_runtime *oruntime = other->runtime;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                oruntime->status->hw_ptr =
                                    runtime->status->hw_ptr;
@@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
 
        /* Memory allocation, takashi's method, dont know if we should spinlock  */
        /* malloc all buffer even if not enabled to get sure */
-       /* malloc only needed bytes */
+       /* Update for MADI rev 204: we need to allocate for all channels,
+        * otherwise it doesn't work at 96kHz */
        err =
-           snd_pcm_lib_malloc_pages(substream,
-                                    HDSPM_CHANNEL_BUFFER_BYTES *
-                                    params_channels(params));
+           snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
        if (err < 0)
                return err;
 
@@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
           "playback" : "capture",
           snd_pcm_sgbuf_get_addr(sgbuf, 0));
         */
+       /*
+       snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                         "playback" : "capture",
+                       params_rate(params), params_channels(params),
+                       params_buffer_size(params));
+       */
        return 0;
 }
 
@@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
                other = hdspm->playback_substream;
 
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                snd_pcm_trigger_done(s, substream);
                                if (cmd == SNDRV_PCM_TRIGGER_START)
@@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
        struct snd_interval *r =
            hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 
-       if (r->min > 48000) {
+       if (r->min > 48000 && r->max <= 96000) {
                struct snd_interval t = {
-                       .min = 1,
+                       .min = hdspm->ds_channels,
                        .max = hdspm->ds_channels,
                        .integer = 1,
                };
                return snd_interval_refine(c, &t);
        } else if (r->max < 64000) {
                struct snd_interval t = {
-                       .min = 1,
+                       .min = hdspm->ss_channels,
                        .max = hdspm->ss_channels,
                        .integer = 1,
                };
@@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
        struct snd_interval *r =
            hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 
-       if (c->min <= hdspm->ss_channels) {
+       if (c->min >= hdspm->ss_channels) {
                struct snd_interval t = {
                        .min = 32000,
                        .max = 48000,
                        .integer = 1,
                };
                return snd_interval_refine(r, &t);
-       } else if (c->max > hdspm->ss_channels) {
+       } else if (c->max <= hdspm->ds_channels) {
                struct snd_interval t = {
                        .min = 64000,
                        .max = 96000,
@@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
        return 0;
 }
 
+static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params,
+                                     struct snd_pcm_hw_rule *rule)
+{
+       unsigned int list[3];
+       struct hdspm *hdspm = rule->private;
+       struct snd_interval *c = hw_param_interval(params,
+                       SNDRV_PCM_HW_PARAM_CHANNELS);
+       if (hdspm->is_aes32) {
+               list[0] = hdspm->qs_channels;
+               list[1] = hdspm->ds_channels;
+               list[2] = hdspm->ss_channels;
+               return snd_interval_list(c, 3, list, 0);
+       } else {
+               list[0] = hdspm->ds_channels;
+               list[1] = hdspm->ss_channels;
+               return snd_interval_list(c, 2, list, 0);
+       }
+}
+
+
+static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
+
+static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = {
+       .count = ARRAY_SIZE(hdspm_aes32_sample_rates),
+       .list = hdspm_aes32_sample_rates,
+       .mask = 0
+};
+
 static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
 {
        struct hdspm *hdspm = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       snd_printdd("Open device substream %d\n", substream->stream);
-
        spin_lock_irq(&hdspm->lock);
 
        snd_pcm_set_sync(substream);
@@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
                                   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
                                   &hw_constraints_period_sizes);
 
-       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                           snd_hdspm_hw_rule_channels_rate, hdspm,
-                           SNDRV_PCM_HW_PARAM_RATE, -1);
-
-       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                           snd_hdspm_hw_rule_rate_channels, hdspm,
-                           SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
+       if (hdspm->is_aes32) {
+               snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                               &hdspm_hw_constraints_aes32_sample_rates);
+       } else {
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                    snd_hdspm_hw_rule_channels, hdspm,
+                                    SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                   snd_hdspm_hw_rule_channels_rate, hdspm,
+                                   SNDRV_PCM_HW_PARAM_RATE, -1);
+
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                   snd_hdspm_hw_rule_rate_channels, hdspm,
+                                   SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+       }
        return 0;
 }
 
@@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
        snd_pcm_hw_constraint_list(runtime, 0,
                                   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
                                   &hw_constraints_period_sizes);
-
-       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                           snd_hdspm_hw_rule_channels_rate, hdspm,
-                           SNDRV_PCM_HW_PARAM_RATE, -1);
-
-       snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                           snd_hdspm_hw_rule_rate_channels, hdspm,
-                           SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+       if (hdspm->is_aes32) {
+               snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                               &hdspm_hw_constraints_aes32_sample_rates);
+       } else {
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                    snd_hdspm_hw_rule_channels, hdspm,
+                                    SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                   snd_hdspm_hw_rule_channels_rate, hdspm,
+                                   SNDRV_PCM_HW_PARAM_RATE, -1);
+
+               snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                   snd_hdspm_hw_rule_rate_channels, hdspm,
+                                   SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+       }
        return 0;
 }
 
index cc3bdececce769e8f9e1fb7ab808c4639b1b33d1..bd7dbd267ed1b10e09c81023bce90ca9f57c2211 100644 (file)
@@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream)
        else
                runtime->status->hw_ptr = 0;
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
                struct snd_pcm_runtime *oruntime = other->runtime;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                oruntime->status->hw_ptr = runtime->status->hw_ptr;
                                break;
@@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
                other = rme9652->playback_substream;
 
        if (other) {
-               struct list_head *pos;
                struct snd_pcm_substream *s;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == other) {
                                snd_pcm_trigger_done(s, substream);
                                if (cmd == SNDRV_PCM_TRIGGER_START)
index 3bff32167f6617a13be87b4d215e43f8bf4e1c99..7ca6062724602f0a8cc9395d0231edcd2ede787c 100644 (file)
@@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
                                    
 {
        struct snd_trident *trident = snd_pcm_substream_chip(substream);
-       struct list_head *pos;
        struct snd_pcm_substream *s;
        unsigned int what, whati, capture_flag, spdif_flag;
        struct snd_trident_voice *voice, *evoice;
@@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
        what = whati = capture_flag = spdif_flag = 0;
        spin_lock(&trident->reg_lock);
        val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
-       snd_pcm_group_for_each(pos, substream) {
-               s = snd_pcm_group_substream_entry(pos);
+       snd_pcm_group_for_each_entry(s, substream) {
                if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
                        voice = s->runtime->private_data;
                        evoice = voice->extra;
index fd12674d03943329e1bb224bce4805b655663d06..ea861bceaddfa3f8cf1281efe9a90ca69688d611 100644 (file)
@@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
        }
 }
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
 
 #include "ymfpci_image.h"
 
@@ -2018,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = {
 };
 #endif
 
+#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
+static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
+{
+       chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
+       if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
+           chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
+           chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
+           chip->device_id == PCI_DEVICE_ID_YAMAHA_754)
+               chip->controller_microcode =
+                       &snd_ymfpci_controller_1e_microcode;
+       else
+               chip->controller_microcode =
+                       &snd_ymfpci_controller_microcode;
+       return 0;
+}
+
+#else /* use fw_loader */
+
 #ifdef __LITTLE_ENDIAN
 static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { }
 #else
@@ -2046,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
                        err = -EINVAL;
                }
        }
-       if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-               chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
-#else
+       if (err < 0)
                return err;
-#endif
-       }
        is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
                chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
                chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
@@ -2069,18 +2080,17 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
                        err = -EINVAL;
                }
        }
-       if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-               chip->controller_microcode =
-                       is_1e ? &snd_ymfpci_controller_1e_microcode
-                             : &snd_ymfpci_controller_microcode;
-#else
+       if (err < 0)
                return err;
-#endif
-       }
        return 0;
 }
 
+MODULE_FIRMWARE("yamaha/ds1_dsp.fw");
+MODULE_FIRMWARE("yamaha/ds1_ctrl.fw");
+MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw");
+
+#endif
+
 static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
 {
        int i;
@@ -2259,15 +2269,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
        pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
        
        pci_disable_device(chip->pci);
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode)
-#endif
-               release_firmware(chip->dsp_microcode);
-#ifdef FIRMWARE_IN_THE_KERNEL
-       if (chip->controller_microcode != &snd_ymfpci_controller_microcode &&
-           chip->controller_microcode != &snd_ymfpci_controller_1e_microcode)
+#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
+       release_firmware(chip->dsp_microcode);
+       release_firmware(chip->controller_microcode);
 #endif
-               release_firmware(chip->controller_microcode);
        kfree(chip);
        return 0;
 }
index 363bcb5f08e671c6d085e42e717afba5057d6035..c57e127d9ccb1fd98b14666d716b6f2d40cfcb75 100644 (file)
@@ -297,7 +297,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev)
 
        /* find an empty slot from the card list */
        for (i = 0; i < SNDRV_CARDS; i++) {
-               if (! card_alloc & (1 << i))
+               if (!(card_alloc & (1 << i)))
                        break;
        }
        if (i >= SNDRV_CARDS) {
index dccaa4be679edb2321b832ecf6645d7c4aa2503f..10cffc0871816597f7ee65f9560bc41fce26208d 100644 (file)
@@ -2,31 +2,31 @@
 # SoC audio configuration
 #
 
-menu "SoC audio support"
+menu "System on Chip audio support"
        depends on SND!=n
 
 config SND_SOC_AC97_BUS
        bool
 
 config SND_SOC
-       tristate "SoC audio support"
+       tristate "ALSA for SoC audio support"
        depends on SND
        select SND_PCM
        ---help---
 
-         If you want SoC support, you should say Y here and also to the
-         specific driver for your SoC below. You will also need to select the
-         specific codec(s) attached to the SoC
+         If you want ASoC support, you should say Y here and also to the
+         specific driver for your SoC platform below.
+         
+         ASoC provides power efficient ALSA support for embedded battery powered
+         SoC based systems like PDA's, Phones and Personal Media Players.
 
-         This SoC audio support can also be built as a module.  If so, the module
+         This ASoC audio support can also be built as a module.  If so, the module
          will be called snd-soc-core.
 
 # All the supported Soc's
-menu "SoC Platforms"
-depends on SND_SOC
 source "sound/soc/at91/Kconfig"
 source "sound/soc/pxa/Kconfig"
-endmenu
+source "sound/soc/s3c24xx/Kconfig"
 
 # Supported codecs
 source "sound/soc/codecs/Kconfig"
index 98e6f49dafc2a5a4167b6d17f2182925e4f79c46..0ae2e49036f9050bffa9701129cb1bd4f69665d6 100644 (file)
@@ -1,4 +1,4 @@
 snd-soc-core-objs := soc-core.o soc-dapm.o
 
 obj-$(CONFIG_SND_SOC)  += snd-soc-core.o
-obj-$(CONFIG_SND_SOC)  += codecs/ at91/ pxa/
+obj-$(CONFIG_SND_SOC)  += codecs/ at91/ pxa/ s3c24xx/
index a5b2558916c1124eb0d9a3c2017f32920873d24a..5cb93fd3a4071d477cd38bab269b2bbfe2fda50d 100644 (file)
@@ -1,5 +1,3 @@
-menu "SoC Audio for the Atmel AT91"
-
 config SND_AT91_SOC
        tristate "SoC Audio for the Atmel AT91 System-on-Chip"
        depends on ARCH_AT91 && SND_SOC
@@ -8,13 +6,13 @@ config SND_AT91_SOC
          the AT91 SSC interface. You will also need
          to select the audio interfaces to support below.
 
-config SND_AT91_SOC_I2S
+config SND_AT91_SOC_SSC
        tristate
 
 config SND_AT91_SOC_ETI_B1_WM8731
-       tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards"
+       tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
        depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
-       select SND_AT91_SOC_I2S
+       select SND_AT91_SOC_SSC
        select SND_SOC_WM8731
        help
          Say Y if you want to add support for SoC audio on WM8731-based
@@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE
        help
          Say Y if you want to run with the AT91 SSC generating the BCLK
          and LRC signals on Endrelia boards.
-
-endmenu
index b77b01ab2028e03c3d4394c56b1f45b1105690f1..f23da17cc3288e0e11ac2e951ffcf2a14b3e87bd 100644 (file)
@@ -1,9 +1,9 @@
 # AT91 Platform Support
 snd-soc-at91-objs := at91-pcm.o
-snd-soc-at91-i2s-objs := at91-i2s.o
+snd-soc-at91-ssc-objs := at91-ssc.o
 
 obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
-obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o
+obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
 
 # AT91 Machine Support
 snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
diff --git a/sound/soc/at91/at91-i2s.c b/sound/soc/at91/at91-i2s.c
deleted file mode 100644 (file)
index 9fc0c03..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * at91-i2s.c  --  ALSA SoC I2S Audio Layer Platform driver
- *
- * Author: Frank Mandarino <fmandarino@endrelia.com>
- *         Endrelia Technologies Inc.
- *
- * Based on pxa2xx Platform drivers by
- * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/atmel_pdc.h>
-
-#include <sound/driver.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_ssc.h>
-
-#include "at91-pcm.h"
-#include "at91-i2s.h"
-
-#if 0
-#define        DBG(x...)       printk(KERN_DEBUG "at91-i2s:" x)
-#else
-#define        DBG(x...)
-#endif
-
-#if defined(CONFIG_ARCH_AT91SAM9260)
-#define NUM_SSC_DEVICES                1
-#else
-#define NUM_SSC_DEVICES                3
-#endif
-
-
-/*
- * SSC PDC registers required by the PCM DMA engine.
- */
-static struct at91_pdc_regs pdc_tx_reg = {
-       .xpr            = ATMEL_PDC_TPR,
-       .xcr            = ATMEL_PDC_TCR,
-       .xnpr           = ATMEL_PDC_TNPR,
-       .xncr           = ATMEL_PDC_TNCR,
-};
-
-static struct at91_pdc_regs pdc_rx_reg = {
-       .xpr            = ATMEL_PDC_RPR,
-       .xcr            = ATMEL_PDC_RCR,
-       .xnpr           = ATMEL_PDC_RNPR,
-       .xncr           = ATMEL_PDC_RNCR,
-};
-
-/*
- * SSC & PDC status bits for transmit and receive.
- */
-static struct at91_ssc_mask ssc_tx_mask = {
-       .ssc_enable     = AT91_SSC_TXEN,
-       .ssc_disable    = AT91_SSC_TXDIS,
-       .ssc_endx       = AT91_SSC_ENDTX,
-       .ssc_endbuf     = AT91_SSC_TXBUFE,
-       .pdc_enable     = ATMEL_PDC_TXTEN,
-       .pdc_disable    = ATMEL_PDC_TXTDIS,
-};
-
-static struct at91_ssc_mask ssc_rx_mask = {
-       .ssc_enable     = AT91_SSC_RXEN,
-       .ssc_disable    = AT91_SSC_RXDIS,
-       .ssc_endx       = AT91_SSC_ENDRX,
-       .ssc_endbuf     = AT91_SSC_RXBUFF,
-       .pdc_enable     = ATMEL_PDC_RXTEN,
-       .pdc_disable    = ATMEL_PDC_RXTDIS,
-};
-
-
-/*
- * DMA parameters.
- */
-static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
-       {{
-       .name           = "SSC0/I2S PCM Stereo out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC0/I2S PCM Stereo in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-#if NUM_SSC_DEVICES == 3
-       {{
-       .name           = "SSC1/I2S PCM Stereo out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC1/I2S PCM Stereo in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-       {{
-       .name           = "SSC2/I2S PCM Stereo out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC1/I2S PCM Stereo in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-#endif
-};
-
-struct at91_ssc_state {
-       u32     ssc_cmr;
-       u32     ssc_rcmr;
-       u32     ssc_rfmr;
-       u32     ssc_tcmr;
-       u32     ssc_tfmr;
-       u32     ssc_sr;
-       u32     ssc_imr;
-};
-
-static struct at91_ssc_info {
-       char            *name;
-       struct at91_ssc_periph ssc;
-       spinlock_t      lock;           /* lock for dir_mask */
-       unsigned short  dir_mask;       /* 0=unused, 1=playback, 2=capture */
-       unsigned short  initialized;    /* 1=SSC has been initialized */
-       unsigned short  daifmt;
-       unsigned short  cmr_div;
-       unsigned short  tcmr_period;
-       unsigned short  rcmr_period;
-       struct at91_pcm_dma_params *dma_params[2];
-       struct at91_ssc_state ssc_state;
-
-} ssc_info[NUM_SSC_DEVICES] = {
-       {
-       .name           = "ssc0",
-       .lock           = SPIN_LOCK_UNLOCKED,
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-#if NUM_SSC_DEVICES == 3
-       {
-       .name           = "ssc1",
-       .lock           = SPIN_LOCK_UNLOCKED,
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-       {
-       .name           = "ssc2",
-       .lock           = SPIN_LOCK_UNLOCKED,
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-#endif
-};
-
-static unsigned int at91_i2s_sysclk;
-
-/*
- * SSC interrupt handler.  Passes PDC interrupts to the DMA
- * interrupt handler in the PCM driver.
- */
-static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id)
-{
-       struct at91_ssc_info *ssc_p = dev_id;
-       struct at91_pcm_dma_params *dma_params;
-       u32 ssc_sr;
-       int i;
-
-       ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
-                       & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
-
-       /*
-        * Loop through the substreams attached to this SSC.  If
-        * a DMA-related interrupt occurred on that substream, call
-        * the DMA interrupt handler function, if one has been
-        * registered in the dma_params structure by the PCM driver.
-        */
-       for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
-               dma_params = ssc_p->dma_params[i];
-
-               if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
-                       (ssc_sr &
-                       (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
-
-                       dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * Startup.  Only that one substream allowed in each direction.
- */
-static int at91_i2s_startup(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       int dir_mask;
-
-       DBG("i2s_startup: SSC_SR=0x%08lx\n",
-                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
-       dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
-
-       spin_lock_irq(&ssc_p->lock);
-       if (ssc_p->dir_mask & dir_mask) {
-               spin_unlock_irq(&ssc_p->lock);
-               return -EBUSY;
-       }
-       ssc_p->dir_mask |= dir_mask;
-       spin_unlock_irq(&ssc_p->lock);
-
-       return 0;
-}
-
-/*
- * Shutdown.  Clear DMA parameters and shutdown the SSC if there
- * are no other substreams open.
- */
-static void at91_i2s_shutdown(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir, dir_mask;
-
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-       dma_params = ssc_p->dma_params[dir];
-
-       if (dma_params != NULL) {
-               at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
-                               dma_params->mask->ssc_disable);
-               DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
-                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
-
-               dma_params->ssc_base = NULL;
-               dma_params->substream = NULL;
-               ssc_p->dma_params[dir] = NULL;
-       }
-
-       dir_mask = 1 << dir;
-
-       spin_lock_irq(&ssc_p->lock);
-       ssc_p->dir_mask &= ~dir_mask;
-       if (!ssc_p->dir_mask) {
-               /* Shutdown the SSC clock. */
-               DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-               at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
-
-               if (ssc_p->initialized) {
-                       free_irq(ssc_p->ssc.pid, ssc_p);
-                       ssc_p->initialized = 0;
-               }
-
-               /* Reset the SSC */
-               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
-
-               /* Clear the SSC dividers */
-               ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
-       }
-       spin_unlock_irq(&ssc_p->lock);
-}
-
-/*
- * Record the SSC system clock rate.
- */
-static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
-               int clk_id, unsigned int freq, int dir)
-{
-       /*
-        * The only clock supplied to the SSC is the AT91 master clock,
-        * which is only used if the SSC is generating BCLK and/or
-        * LRC clocks.
-        */
-       switch (clk_id) {
-       case AT91_SYSCLK_MCK:
-               at91_i2s_sysclk = freq;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * Record the DAI format for use in hw_params().
- */
-static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
-               unsigned int fmt)
-{
-       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S)
-               return -EINVAL;
-
-       ssc_p->daifmt = fmt;
-       return 0;
-}
-
-/*
- * Record SSC clock dividers for use in hw_params().
- */
-static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
-       int div_id, int div)
-{
-       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       switch (div_id) {
-       case AT91SSC_CMR_DIV:
-               /*
-                * The same master clock divider is used for both
-                * transmit and receive, so if a value has already
-                * been set, it must match this value.
-                */
-               if (ssc_p->cmr_div == 0)
-                       ssc_p->cmr_div = div;
-               else
-                       if (div != ssc_p->cmr_div)
-                               return -EBUSY;
-               break;
-
-       case AT91SSC_TCMR_PERIOD:
-               ssc_p->tcmr_period = div;
-               break;
-
-       case AT91SSC_RCMR_PERIOD:
-               ssc_p->rcmr_period = div;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * Configure the SSC.
- */
-static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int id = rtd->dai->cpu_dai->id;
-       struct at91_ssc_info *ssc_p = &ssc_info[id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir, channels, bits;
-       u32 tfmr, rfmr, tcmr, rcmr;
-       int start_event;
-       int ret;
-
-       /*
-        * Currently, there is only one set of dma params for
-        * each direction.  If more are added, this code will
-        * have to be changed to select the proper set.
-        */
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-
-       dma_params = &ssc_dma_params[id][dir];
-       dma_params->ssc_base = ssc_p->ssc.base;
-       dma_params->substream = substream;
-
-       ssc_p->dma_params[dir] = dma_params;
-
-       /*
-        * The cpu_dai->dma_data field is only used to communicate the
-        * appropriate DMA parameters to the pcm driver hw_params()
-        * function.  It should not be used for other purposes
-        * as it is common to all substreams.
-        */
-       rtd->dai->cpu_dai->dma_data = dma_params;
-
-       channels = params_channels(params);
-
-       /*
-        * The SSC only supports up to 16-bit samples in I2S format, due
-        * to the size of the Frame Mode Register FSLEN field.  Also, I2S
-        * implies signed data.
-        */
-       bits = 16;
-       dma_params->pdc_xfer_size = 2;
-
-       /*
-        * Compute SSC register settings.
-        */
-       switch (ssc_p->daifmt) {
-       case SND_SOC_DAIFMT_CBS_CFS:
-               /*
-                * SSC provides BCLK and LRC clocks.
-                *
-                * The SSC transmit and receive clocks are generated from the
-                * MCK divider, and the BCLK signal is output on the SSC TK line.
-                */
-               rcmr =    (( ssc_p->rcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
-                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_LOOP)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-               tcmr =    (( ssc_p->tcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
-                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_CONTINUOUS         ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( 0                          << 23) & AT91_SSC_FSDEN)
-                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
-                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-               break;
-
-       case SND_SOC_DAIFMT_CBM_CFM:
-
-               /*
-                * CODEC supplies BCLK and LRC clocks.
-                *
-                * The SSC transmit clock is obtained from the BCLK signal on
-                * on the TK line, and the SSC receive clock is generated from the
-                * transmit clock.
-                *
-                * For single channel data, one sample is transferred on the falling
-                * edge of the LRC clock.  For two channel data, one sample is
-                * transferred on both edges of the LRC clock.
-                */
-               start_event = channels == 1
-                               ? AT91_SSC_START_FALLING_RF
-                               : AT91_SSC_START_EDGE_RF;
-
-               rcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( start_event                     ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_CLOCK              ) & AT91_SSC_CKS);
-
-               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (( 0                          <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_LOOP)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-               tcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( start_event                     ) & AT91_SSC_START)
-                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_PIN                ) & AT91_SSC_CKS);
-
-               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( 0                          << 23) & AT91_SSC_FSDEN)
-                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (( 0                          <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-               break;
-
-       case SND_SOC_DAIFMT_CBS_CFM:
-       case SND_SOC_DAIFMT_CBM_CFS:
-       default:
-               printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n",
-                       ssc_p->daifmt);
-               return -EINVAL;
-               break;
-       }
-       DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
-
-       if (!ssc_p->initialized) {
-
-               /* Enable PMC peripheral clock for this SSC */
-               DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
-               at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
-
-               /* Reset the SSC and its PDC registers */
-               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
-
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
-
-               if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt,
-                                       0, ssc_p->name, ssc_p)) < 0) {
-                       printk(KERN_WARNING "at91-i2s: request_irq failure\n");
-
-                       DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-                       at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
-                       return ret;
-               }
-
-               ssc_p->initialized = 1;
-       }
-
-       /* set SSC clock mode register */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
-
-       /* set receive clock mode and format */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
-
-       /* set transmit clock mode and format */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
-
-       DBG("hw_params: SSC initialized\n");
-       return 0;
-}
-
-
-static int at91_i2s_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir;
-
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-       dma_params = ssc_p->dma_params[dir];
-
-       at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
-                       dma_params->mask->ssc_enable);
-
-       DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
-               at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
-       return 0;
-}
-
-
-#ifdef CONFIG_PM
-static int at91_i2s_suspend(struct platform_device *pdev,
-       struct snd_soc_cpu_dai *cpu_dai)
-{
-       struct at91_ssc_info *ssc_p;
-
-       if(!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       /* Save the status register before disabling transmit and receive. */
-       ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
-                       AT91_SSC_TXDIS | AT91_SSC_RXDIS);
-
-       /* Save the current interrupt mask, then disable unmasked interrupts. */
-       ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
-
-       ssc_p->ssc_state.ssc_cmr  = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
-       ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
-       ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
-       ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
-       ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
-
-       return 0;
-}
-
-static int at91_i2s_resume(struct platform_device *pdev,
-       struct snd_soc_cpu_dai *cpu_dai)
-{
-       struct at91_ssc_info *ssc_p;
-
-       if(!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR,  ssc_p->ssc_state.ssc_cmr);
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER,  ssc_p->ssc_state.ssc_imr);
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
-               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
-               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
-
-       return 0;
-}
-
-#else
-#define at91_i2s_suspend       NULL
-#define at91_i2s_resume                NULL
-#endif
-
-#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
-                       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
-                       SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
-                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
-                       SNDRV_PCM_RATE_96000)
-
-struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = {
-       {       .name = "at91_ssc0/i2s",
-               .id = 0,
-               .type = SND_SOC_DAI_I2S,
-               .suspend = at91_i2s_suspend,
-               .resume = at91_i2s_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .ops = {
-                       .startup = at91_i2s_startup,
-                       .shutdown = at91_i2s_shutdown,
-                       .prepare = at91_i2s_prepare,
-                       .hw_params = at91_i2s_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_i2s_set_dai_sysclk,
-                       .set_fmt = at91_i2s_set_dai_fmt,
-                       .set_clkdiv = at91_i2s_set_dai_clkdiv,},
-               .private_data = &ssc_info[0].ssc,
-       },
-#if NUM_SSC_DEVICES == 3
-       {       .name = "at91_ssc1/i2s",
-               .id = 1,
-               .type = SND_SOC_DAI_I2S,
-               .suspend = at91_i2s_suspend,
-               .resume = at91_i2s_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .ops = {
-                       .startup = at91_i2s_startup,
-                       .shutdown = at91_i2s_shutdown,
-                       .prepare = at91_i2s_prepare,
-                       .hw_params = at91_i2s_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_i2s_set_dai_sysclk,
-                       .set_fmt = at91_i2s_set_dai_fmt,
-                       .set_clkdiv = at91_i2s_set_dai_clkdiv,},
-               .private_data = &ssc_info[1].ssc,
-       },
-       {       .name = "at91_ssc2/i2s",
-               .id = 2,
-               .type = SND_SOC_DAI_I2S,
-               .suspend = at91_i2s_suspend,
-               .resume = at91_i2s_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_I2S_RATES,
-                       .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-               .ops = {
-                       .startup = at91_i2s_startup,
-                       .shutdown = at91_i2s_shutdown,
-                       .prepare = at91_i2s_prepare,
-                       .hw_params = at91_i2s_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_i2s_set_dai_sysclk,
-                       .set_fmt = at91_i2s_set_dai_fmt,
-                       .set_clkdiv = at91_i2s_set_dai_clkdiv,},
-               .private_data = &ssc_info[2].ssc,
-       },
-#endif
-};
-
-EXPORT_SYMBOL_GPL(at91_i2s_dai);
-
-/* Module information */
-MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
-MODULE_DESCRIPTION("AT91 I2S ASoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-i2s.h b/sound/soc/at91/at91-i2s.h
deleted file mode 100644 (file)
index f8a875b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC
- *
- * Author:     Frank Mandarino <fmandarino@endrelia.com>
- *             Endrelia Technologies Inc.
- * Created:    Jan 9, 2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AT91_I2S_H
-#define _AT91_I2S_H
-
-/* I2S system clock ids */
-#define AT91_SYSCLK_MCK                0 /* SSC uses AT91 MCK as system clock */
-
-/* I2S divider ids */
-#define AT91SSC_CMR_DIV                0 /* MCK divider for BCLK */
-#define AT91SSC_TCMR_PERIOD    1 /* BCLK divider for transmit FS */
-#define AT91SSC_RCMR_PERIOD    2 /* BCLK divider for receive FS */
-
-extern struct snd_soc_cpu_dai at91_i2s_dai[];
-
-#endif /* _AT91_I2S_H */
-
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
new file mode 100644 (file)
index 0000000..3d4e32c
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ * at91-ssc.c  --  ALSA SoC AT91 SSC Audio Layer Platform driver
+ *
+ * Author: Frank Mandarino <fmandarino@endrelia.com>
+ *         Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx Platform drivers by
+ * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/atmel_pdc.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_ssc.h>
+
+#include "at91-pcm.h"
+#include "at91-ssc.h"
+
+#if 0
+#define        DBG(x...)       printk(KERN_DEBUG "at91-ssc:" x)
+#else
+#define        DBG(x...)
+#endif
+
+#if defined(CONFIG_ARCH_AT91SAM9260)
+#define NUM_SSC_DEVICES                1
+#else
+#define NUM_SSC_DEVICES                3
+#endif
+
+
+/*
+ * SSC PDC registers required by the PCM DMA engine.
+ */
+static struct at91_pdc_regs pdc_tx_reg = {
+       .xpr            = ATMEL_PDC_TPR,
+       .xcr            = ATMEL_PDC_TCR,
+       .xnpr           = ATMEL_PDC_TNPR,
+       .xncr           = ATMEL_PDC_TNCR,
+};
+
+static struct at91_pdc_regs pdc_rx_reg = {
+       .xpr            = ATMEL_PDC_RPR,
+       .xcr            = ATMEL_PDC_RCR,
+       .xnpr           = ATMEL_PDC_RNPR,
+       .xncr           = ATMEL_PDC_RNCR,
+};
+
+/*
+ * SSC & PDC status bits for transmit and receive.
+ */
+static struct at91_ssc_mask ssc_tx_mask = {
+       .ssc_enable     = AT91_SSC_TXEN,
+       .ssc_disable    = AT91_SSC_TXDIS,
+       .ssc_endx       = AT91_SSC_ENDTX,
+       .ssc_endbuf     = AT91_SSC_TXBUFE,
+       .pdc_enable     = ATMEL_PDC_TXTEN,
+       .pdc_disable    = ATMEL_PDC_TXTDIS,
+};
+
+static struct at91_ssc_mask ssc_rx_mask = {
+       .ssc_enable     = AT91_SSC_RXEN,
+       .ssc_disable    = AT91_SSC_RXDIS,
+       .ssc_endx       = AT91_SSC_ENDRX,
+       .ssc_endbuf     = AT91_SSC_RXBUFF,
+       .pdc_enable     = ATMEL_PDC_RXTEN,
+       .pdc_disable    = ATMEL_PDC_RXTDIS,
+};
+
+
+/*
+ * DMA parameters.
+ */
+static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
+       {{
+       .name           = "SSC0 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC0 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       }},
+#if NUM_SSC_DEVICES == 3
+       {{
+       .name           = "SSC1 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC1 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       }},
+       {{
+       .name           = "SSC2 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC2 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       }},
+#endif
+};
+
+struct at91_ssc_state {
+       u32     ssc_cmr;
+       u32     ssc_rcmr;
+       u32     ssc_rfmr;
+       u32     ssc_tcmr;
+       u32     ssc_tfmr;
+       u32     ssc_sr;
+       u32     ssc_imr;
+};
+
+static struct at91_ssc_info {
+       char            *name;
+       struct at91_ssc_periph ssc;
+       spinlock_t      lock;           /* lock for dir_mask */
+       unsigned short  dir_mask;       /* 0=unused, 1=playback, 2=capture */
+       unsigned short  initialized;    /* 1=SSC has been initialized */
+       unsigned short  daifmt;
+       unsigned short  cmr_div;
+       unsigned short  tcmr_period;
+       unsigned short  rcmr_period;
+       struct at91_pcm_dma_params *dma_params[2];
+       struct at91_ssc_state ssc_state;
+
+} ssc_info[NUM_SSC_DEVICES] = {
+       {
+       .name           = "ssc0",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
+       .dir_mask       = 0,
+       .initialized    = 0,
+       },
+#if NUM_SSC_DEVICES == 3
+       {
+       .name           = "ssc1",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
+       .dir_mask       = 0,
+       .initialized    = 0,
+       },
+       {
+       .name           = "ssc2",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
+       .dir_mask       = 0,
+       .initialized    = 0,
+       },
+#endif
+};
+
+static unsigned int at91_ssc_sysclk;
+
+/*
+ * SSC interrupt handler.  Passes PDC interrupts to the DMA
+ * interrupt handler in the PCM driver.
+ */
+static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
+{
+       struct at91_ssc_info *ssc_p = dev_id;
+       struct at91_pcm_dma_params *dma_params;
+       u32 ssc_sr;
+       int i;
+
+       ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
+                       & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
+
+       /*
+        * Loop through the substreams attached to this SSC.  If
+        * a DMA-related interrupt occurred on that substream, call
+        * the DMA interrupt handler function, if one has been
+        * registered in the dma_params structure by the PCM driver.
+        */
+       for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
+               dma_params = ssc_p->dma_params[i];
+
+               if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
+                       (ssc_sr &
+                       (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
+
+                       dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * Startup.  Only that one substream allowed in each direction.
+ */
+static int at91_ssc_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       int dir_mask;
+
+       DBG("ssc_startup: SSC_SR=0x%08lx\n",
+                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
+       dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
+
+       spin_lock_irq(&ssc_p->lock);
+       if (ssc_p->dir_mask & dir_mask) {
+               spin_unlock_irq(&ssc_p->lock);
+               return -EBUSY;
+       }
+       ssc_p->dir_mask |= dir_mask;
+       spin_unlock_irq(&ssc_p->lock);
+
+       return 0;
+}
+
+/*
+ * Shutdown.  Clear DMA parameters and shutdown the SSC if there
+ * are no other substreams open.
+ */
+static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       struct at91_pcm_dma_params *dma_params;
+       int dir, dir_mask;
+
+       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
+       dma_params = ssc_p->dma_params[dir];
+
+       if (dma_params != NULL) {
+               at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
+                               dma_params->mask->ssc_disable);
+               DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
+                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
+
+               dma_params->ssc_base = NULL;
+               dma_params->substream = NULL;
+               ssc_p->dma_params[dir] = NULL;
+       }
+
+       dir_mask = 1 << dir;
+
+       spin_lock_irq(&ssc_p->lock);
+       ssc_p->dir_mask &= ~dir_mask;
+       if (!ssc_p->dir_mask) {
+               /* Shutdown the SSC clock. */
+               DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
+               at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
+
+               if (ssc_p->initialized) {
+                       free_irq(ssc_p->ssc.pid, ssc_p);
+                       ssc_p->initialized = 0;
+               }
+
+               /* Reset the SSC */
+               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
+
+               /* Clear the SSC dividers */
+               ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
+       }
+       spin_unlock_irq(&ssc_p->lock);
+}
+
+/*
+ * Record the SSC system clock rate.
+ */
+static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
+               int clk_id, unsigned int freq, int dir)
+{
+       /*
+        * The only clock supplied to the SSC is the AT91 master clock,
+        * which is only used if the SSC is generating BCLK and/or
+        * LRC clocks.
+        */
+       switch (clk_id) {
+       case AT91_SYSCLK_MCK:
+               at91_ssc_sysclk = freq;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * Record the DAI format for use in hw_params().
+ */
+static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
+               unsigned int fmt)
+{
+       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+
+       ssc_p->daifmt = fmt;
+       return 0;
+}
+
+/*
+ * Record SSC clock dividers for use in hw_params().
+ */
+static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
+       int div_id, int div)
+{
+       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+
+       switch (div_id) {
+       case AT91SSC_CMR_DIV:
+               /*
+                * The same master clock divider is used for both
+                * transmit and receive, so if a value has already
+                * been set, it must match this value.
+                */
+               if (ssc_p->cmr_div == 0)
+                       ssc_p->cmr_div = div;
+               else
+                       if (div != ssc_p->cmr_div)
+                               return -EBUSY;
+               break;
+
+       case AT91SSC_TCMR_PERIOD:
+               ssc_p->tcmr_period = div;
+               break;
+
+       case AT91SSC_RCMR_PERIOD:
+               ssc_p->rcmr_period = div;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * Configure the SSC.
+ */
+static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       int id = rtd->dai->cpu_dai->id;
+       struct at91_ssc_info *ssc_p = &ssc_info[id];
+       struct at91_pcm_dma_params *dma_params;
+       int dir, channels, bits;
+       u32 tfmr, rfmr, tcmr, rcmr;
+       int start_event;
+       int ret;
+
+       /*
+        * Currently, there is only one set of dma params for
+        * each direction.  If more are added, this code will
+        * have to be changed to select the proper set.
+        */
+       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
+
+       dma_params = &ssc_dma_params[id][dir];
+       dma_params->ssc_base = ssc_p->ssc.base;
+       dma_params->substream = substream;
+
+       ssc_p->dma_params[dir] = dma_params;
+
+       /*
+        * The cpu_dai->dma_data field is only used to communicate the
+        * appropriate DMA parameters to the pcm driver hw_params()
+        * function.  It should not be used for other purposes
+        * as it is common to all substreams.
+        */
+       rtd->dai->cpu_dai->dma_data = dma_params;
+
+       channels = params_channels(params);
+
+       /*
+        * Determine sample size in bits and the PDC increment.
+        */
+       switch(params_format(params)) {
+       case SNDRV_PCM_FORMAT_S8:
+               bits = 8;
+               dma_params->pdc_xfer_size = 1;
+               break;
+       case SNDRV_PCM_FORMAT_S16_LE:
+               bits = 16;
+               dma_params->pdc_xfer_size = 2;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               bits = 24;
+               dma_params->pdc_xfer_size = 4;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               bits = 32;
+               dma_params->pdc_xfer_size = 4;
+               break;
+       default:
+               printk(KERN_WARNING "at91-ssc: unsupported PCM format");
+               return -EINVAL;
+       }
+
+       /*
+        * The SSC only supports up to 16-bit samples in I2S format, due
+        * to the size of the Frame Mode Register FSLEN field.
+        */
+       if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
+               && bits > 16) {
+               printk(KERN_WARNING
+                       "at91-ssc: sample size %d is too large for I2S\n", bits);
+               return -EINVAL;
+       }
+
+       /*
+        * Compute SSC register settings.
+        */
+       switch (ssc_p->daifmt
+               & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
+
+       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+               /*
+                * I2S format, SSC provides BCLK and LRC clocks.
+                *
+                * The SSC transmit and receive clocks are generated from the
+                * MCK divider, and the BCLK signal is output on the SSC TK line.
+                */
+               rcmr =    (( ssc_p->rcmr_period         << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
+                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
+
+               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
+                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
+                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_LOOP)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+
+               tcmr =    (( ssc_p->tcmr_period         << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
+                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_CONTINUOUS         ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
+
+               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( 0                          << 23) & AT91_SSC_FSDEN)
+                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
+                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
+                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+               break;
+
+       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+               /*
+                * I2S format, CODEC supplies BCLK and LRC clocks.
+                *
+                * The SSC transmit clock is obtained from the BCLK signal on
+                * on the TK line, and the SSC receive clock is generated from the
+                * transmit clock.
+                *
+                * For single channel data, one sample is transferred on the falling
+                * edge of the LRC clock.  For two channel data, one sample is
+                * transferred on both edges of the LRC clock.
+                */
+               start_event = channels == 1
+                               ? AT91_SSC_START_FALLING_RF
+                               : AT91_SSC_START_EDGE_RF;
+
+               rcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( start_event                     ) & AT91_SSC_START)
+                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_CLOCK              ) & AT91_SSC_CKS);
+
+               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
+                       | (( 0                          << 16) & AT91_SSC_FSLEN)
+                       | (( 0                          <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_LOOP)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+
+               tcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( start_event                     ) & AT91_SSC_START)
+                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_PIN                ) & AT91_SSC_CKS);
+
+               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( 0                          << 23) & AT91_SSC_FSDEN)
+                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
+                       | (( 0                          << 16) & AT91_SSC_FSLEN)
+                       | (( 0                          <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+               break;
+
+       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
+               /*
+                * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
+                *
+                * The SSC transmit and receive clocks are generated from the
+                * MCK divider, and the BCLK signal is output on the SSC TK line.
+                */
+               rcmr =    (( ssc_p->rcmr_period         << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( AT91_SSC_START_RISING_RF        ) & AT91_SSC_START)
+                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
+
+               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( AT91_SSC_FSOS_POSITIVE          ) & AT91_SSC_FSOS)
+                       | (( 0                          << 16) & AT91_SSC_FSLEN)
+                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_LOOP)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+
+               tcmr =    (( ssc_p->tcmr_period         << 24) & AT91_SSC_PERIOD)
+                       | (( 1                          << 16) & AT91_SSC_STTDLY)
+                       | (( AT91_SSC_START_RISING_RF        ) & AT91_SSC_START)
+                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
+                       | (( AT91_SSC_CKO_CONTINUOUS         ) & AT91_SSC_CKO)
+                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
+
+               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
+                       | (( 0                          << 23) & AT91_SSC_FSDEN)
+                       | (( AT91_SSC_FSOS_POSITIVE          ) & AT91_SSC_FSOS)
+                       | (( 0                          << 16) & AT91_SSC_FSLEN)
+                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
+                       | (( 1                          <<  7) & AT91_SSC_MSBF)
+                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
+                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
+
+
+
+                       break;
+
+       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
+       default:
+               printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
+                       ssc_p->daifmt);
+               return -EINVAL;
+               break;
+       }
+       DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
+
+       if (!ssc_p->initialized) {
+
+               /* Enable PMC peripheral clock for this SSC */
+               DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
+               at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
+
+               /* Reset the SSC and its PDC registers */
+               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
+
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
+               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
+
+               if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
+                                       0, ssc_p->name, ssc_p)) < 0) {
+                       printk(KERN_WARNING "at91-ssc: request_irq failure\n");
+
+                       DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
+                       at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
+                       return ret;
+               }
+
+               ssc_p->initialized = 1;
+       }
+
+       /* set SSC clock mode register */
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
+
+       /* set receive clock mode and format */
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
+
+       /* set transmit clock mode and format */
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
+
+       DBG("hw_params: SSC initialized\n");
+       return 0;
+}
+
+
+static int at91_ssc_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       struct at91_pcm_dma_params *dma_params;
+       int dir;
+
+       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
+       dma_params = ssc_p->dma_params[dir];
+
+       at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
+                       dma_params->mask->ssc_enable);
+
+       DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
+               at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
+       return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int at91_ssc_suspend(struct platform_device *pdev,
+       struct snd_soc_cpu_dai *cpu_dai)
+{
+       struct at91_ssc_info *ssc_p;
+
+       if(!cpu_dai->active)
+               return 0;
+
+       ssc_p = &ssc_info[cpu_dai->id];
+
+       /* Save the status register before disabling transmit and receive. */
+       ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
+                       AT91_SSC_TXDIS | AT91_SSC_RXDIS);
+
+       /* Save the current interrupt mask, then disable unmasked interrupts. */
+       ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
+
+       ssc_p->ssc_state.ssc_cmr  = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
+       ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
+       ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
+       ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
+       ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
+
+       return 0;
+}
+
+static int at91_ssc_resume(struct platform_device *pdev,
+       struct snd_soc_cpu_dai *cpu_dai)
+{
+       struct at91_ssc_info *ssc_p;
+
+       if(!cpu_dai->active)
+               return 0;
+
+       ssc_p = &ssc_info[cpu_dai->id];
+
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR,  ssc_p->ssc_state.ssc_cmr);
+
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER,  ssc_p->ssc_state.ssc_imr);
+
+       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
+               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
+               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
+
+       return 0;
+}
+
+#else
+#define at91_ssc_suspend       NULL
+#define at91_ssc_resume                NULL
+#endif
+
+#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
+                       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+                       SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+                       SNDRV_PCM_RATE_96000)
+
+#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_LE |\
+                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
+       {       .name = "at91-ssc0",
+               .id = 0,
+               .type = SND_SOC_DAI_PCM,
+               .suspend = at91_ssc_suspend,
+               .resume = at91_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .ops = {
+                       .startup = at91_ssc_startup,
+                       .shutdown = at91_ssc_shutdown,
+                       .prepare = at91_ssc_prepare,
+                       .hw_params = at91_ssc_hw_params,},
+               .dai_ops = {
+                       .set_sysclk = at91_ssc_set_dai_sysclk,
+                       .set_fmt = at91_ssc_set_dai_fmt,
+                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[0].ssc,
+       },
+#if NUM_SSC_DEVICES == 3
+       {       .name = "at91-ssc1",
+               .id = 1,
+               .type = SND_SOC_DAI_PCM,
+               .suspend = at91_ssc_suspend,
+               .resume = at91_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .ops = {
+                       .startup = at91_ssc_startup,
+                       .shutdown = at91_ssc_shutdown,
+                       .prepare = at91_ssc_prepare,
+                       .hw_params = at91_ssc_hw_params,},
+               .dai_ops = {
+                       .set_sysclk = at91_ssc_set_dai_sysclk,
+                       .set_fmt = at91_ssc_set_dai_fmt,
+                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[1].ssc,
+       },
+       {       .name = "at91-ssc2",
+               .id = 2,
+               .type = SND_SOC_DAI_PCM,
+               .suspend = at91_ssc_suspend,
+               .resume = at91_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = AT91_SSC_RATES,
+                       .formats = AT91_SSC_FORMATS,},
+               .ops = {
+                       .startup = at91_ssc_startup,
+                       .shutdown = at91_ssc_shutdown,
+                       .prepare = at91_ssc_prepare,
+                       .hw_params = at91_ssc_hw_params,},
+               .dai_ops = {
+                       .set_sysclk = at91_ssc_set_dai_sysclk,
+                       .set_fmt = at91_ssc_set_dai_fmt,
+                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[2].ssc,
+       },
+#endif
+};
+
+EXPORT_SYMBOL_GPL(at91_ssc_dai);
+
+/* Module information */
+MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
+MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
new file mode 100644 (file)
index 0000000..b188f97
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
+ *
+ * Author:     Frank Mandarino <fmandarino@endrelia.com>
+ *             Endrelia Technologies Inc.
+ * Created:    Jan 9, 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _AT91_SSC_H
+#define _AT91_SSC_H
+
+/* SSC system clock ids */
+#define AT91_SYSCLK_MCK                0 /* SSC uses AT91 MCK as system clock */
+
+/* SSC divider ids */
+#define AT91SSC_CMR_DIV                0 /* MCK divider for BCLK */
+#define AT91SSC_TCMR_PERIOD    1 /* BCLK divider for transmit FS */
+#define AT91SSC_RCMR_PERIOD    2 /* BCLK divider for receive FS */
+
+extern struct snd_soc_cpu_dai at91_ssc_dai[];
+
+#endif /* _AT91_SSC_H */
+
index 8179df3bb2f33cd3a833228ad827d7ece6460a7e..820a676c56bf66e8a0b5ae34023f48646b59d1fd 100644 (file)
@@ -40,7 +40,7 @@
 
 #include "../codecs/wm8731.h"
 #include "at91-pcm.h"
-#include "at91-i2s.h"
+#include "at91-ssc.h"
 
 #if 0
 #define        DBG(x...)       printk(KERN_INFO "eti_b1_wm8731: " x)
@@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
 
 static struct snd_soc_dai_link eti_b1_dai = {
        .name = "WM8731",
-       .stream_name = "WM8731",
-       .cpu_dai = &at91_i2s_dai[1],
+       .stream_name = "WM8731 PCM",
+       .cpu_dai = &at91_ssc_dai[1],
        .codec_dai = &wm8731_dai,
        .init = eti_b1_wm8731_init,
        .ops = &eti_b1_ops,
 };
 
 static struct snd_soc_machine snd_soc_machine_eti_b1 = {
-       .name = "ETI_B1",
+       .name = "ETI_B1_WM8731",
        .dai_link = &eti_b1_dai,
        .num_links = 1,
 };
index ec2a2787957a2d56497dec1dc3bda83f5a7842df..e5fb437b86e82bbcee61a24ab506fb9ca9b11ac0 100644 (file)
@@ -10,6 +10,10 @@ config SND_SOC_WM8750
        tristate
        depends on SND_SOC
 
+config SND_SOC_WM8753
+       tristate
+       depends on SND_SOC
+
 config SND_SOC_WM9712
        tristate
        depends on SND_SOC
index 3249a6e4f1d08f1fe2f6aad0fd992755c36e8901..e39a747a17cf38c6735d30fdd47b50baf0ac6972 100644 (file)
@@ -1,9 +1,11 @@
 snd-soc-ac97-objs := ac97.o
 snd-soc-wm8731-objs := wm8731.o
 snd-soc-wm8750-objs := wm8750.o
+snd-soc-wm8753-objs := wm8753.o
 snd-soc-wm9712-objs := wm9712.o
 
 obj-$(CONFIG_SND_SOC_AC97_CODEC)       += snd-soc-ac97.o
 obj-$(CONFIG_SND_SOC_WM8731)   += snd-soc-wm8731.o
 obj-$(CONFIG_SND_SOC_WM8750)   += snd-soc-wm8750.o
+obj-$(CONFIG_SND_SOC_WM8753)   += snd-soc-wm8753.o
 obj-$(CONFIG_SND_SOC_WM9712)   += snd-soc-wm9712.o
index 55bc55eb6e24a925f1db81869db3989cebee9ed7..0cdef971cbd395158932289f8dd743637afd9c34 100644 (file)
@@ -60,6 +60,7 @@ static struct snd_soc_codec_dai ac97_dai = {
        .ops = {
                .prepare = ac97_prepare,},
 };
+EXPORT_SYMBOL_GPL(ac97_dai);
 
 static unsigned int ac97_read(struct snd_soc_codec *codec,
        unsigned int reg)
index 930ddfc2321a01a3f9876a9bfea278bc16cc09c0..2bf6d69fd0692c204f3a3126edf3eb34ef39249a 100644 (file)
@@ -14,5 +14,6 @@
 #define __LINUX_SND_SOC_AC97_H
 
 extern struct snd_soc_codec_device soc_codec_dev_ac97;
+extern struct snd_soc_codec_dai ac97_dai;
 
 #endif
index 7073e8e294fc5fdfdf5f0c6ea97f8811e98bcd99..28684eeda73845dd4a68745860f19c8631a465cf 100644 (file)
@@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
        codec->dai = &wm8750_dai;
        codec->num_dai = 1;
        codec->reg_cache_size = sizeof(wm8750_reg);
-       codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL);
+       codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL);
        if (codec->reg_cache == NULL)
                return -ENOMEM;
 
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
new file mode 100644 (file)
index 0000000..efced93
--- /dev/null
@@ -0,0 +1,1811 @@
+/*
+ * wm8753.c  --  WM8753 ALSA Soc Audio driver
+ *
+ * Copyright 2003 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Notes:
+ *  The WM8753 is a low power, high quality stereo codec with integrated PCM
+ *  codec designed for portable digital telephony applications.
+ *
+ * Dual DAI:-
+ *
+ * This driver support 2 DAI PCM's. This makes the default PCM available for
+ * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for
+ * voice.
+ *
+ * Please note that the voice PCM can be connected directly to a Bluetooth
+ * codec or GSM modem and thus cannot be read or written to, although it is
+ * available to be configured with snd_hw_params(), etc and kcontrols in the
+ * normal alsa manner.
+ *
+ * Fast DAI switching:-
+ *
+ * The driver can now fast switch between the DAI configurations via a
+ * an alsa kcontrol. This allows the PCM to remain open.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <asm/div64.h>
+
+#include "wm8753.h"
+
+#define AUDIO_NAME "wm8753"
+#define WM8753_VERSION "0.16"
+
+/*
+ * Debug
+ */
+
+#define WM8753_DEBUG 0
+
+#ifdef WM8753_DEBUG
+#define dbg(format, arg...) \
+       printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) \
+       printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
+#define info(format, arg...) \
+       printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+       printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
+
+static int caps_charge = 2000;
+module_param(caps_charge, int, 0);
+MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
+
+static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
+       unsigned int mode);
+
+/* codec private data */
+struct wm8753_priv {
+       unsigned int sysclk;
+       unsigned int pcmclk;
+};
+
+/*
+ * wm8753 register cache
+ * We can't read the WM8753 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8753_reg[] = {
+       0x0008, 0x0000, 0x000a, 0x000a,
+       0x0033, 0x0000, 0x0007, 0x00ff,
+       0x00ff, 0x000f, 0x000f, 0x007b,
+       0x0000, 0x0032, 0x0000, 0x00c3,
+       0x00c3, 0x00c0, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0055,
+       0x0005, 0x0050, 0x0055, 0x0050,
+       0x0055, 0x0050, 0x0055, 0x0079,
+       0x0079, 0x0079, 0x0079, 0x0079,
+       0x0000, 0x0000, 0x0000, 0x0000,
+       0x0097, 0x0097, 0x0000, 0x0004,
+       0x0000, 0x0083, 0x0024, 0x01ba,
+       0x0000, 0x0083, 0x0024, 0x01ba,
+       0x0000, 0x0000
+};
+
+/*
+ * read wm8753 register cache
+ */
+static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
+       unsigned int reg)
+{
+       u16 *cache = codec->reg_cache;
+       if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1))
+               return -1;
+       return cache[reg - 1];
+}
+
+/*
+ * write wm8753 register cache
+ */
+static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
+       unsigned int reg, unsigned int value)
+{
+       u16 *cache = codec->reg_cache;
+       if (reg < 1 || reg > 0x3f)
+               return;
+       cache[reg - 1] = value;
+}
+
+/*
+ * write to the WM8753 register space
+ */
+static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
+       unsigned int value)
+{
+       u8 data[2];
+
+       /* data is
+        *   D15..D9 WM8753 register offset
+        *   D8...D0 register data
+        */
+       data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+       data[1] = value & 0x00ff;
+
+       wm8753_write_reg_cache (codec, reg, value);
+       if (codec->hw_write(codec->control_data, data, 2) == 2)
+               return 0;
+       else
+               return -EIO;
+}
+
+#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
+
+/*
+ * WM8753 Controls
+ */
+static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
+static const char *wm8753_base_filter[] =
+       {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
+       "100Hz @ 8kHz", "200Hz @ 8kHz"};
+static const char *wm8753_treble[] = {"8kHz", "4kHz"};
+static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
+static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
+static const char *wm8753_3d_func[] = {"Capture", "Playback"};
+static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
+static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
+static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
+static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
+static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
+static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
+       "Line 1", "Line 2"};
+static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
+static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
+static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
+static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
+static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
+       "Right PGA"};
+static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
+       "Left + Right"};
+static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
+static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
+static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
+static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
+static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
+       "Analogue Mix Right", "Digital Mono Mix"};
+static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
+       "82Hz @ 8kHz", "170Hz @ 8kHz"};
+static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
+static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
+static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
+static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
+       "Channel Swap"};
+
+static const struct soc_enum wm8753_enum[] = {
+SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
+SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
+SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
+SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
+SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
+SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
+SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
+SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
+SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
+SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
+SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
+SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
+SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
+SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
+SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
+SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
+SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
+SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
+SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
+SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
+};
+
+
+static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+       int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+
+       ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
+       return 0;
+}
+
+static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+       int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+
+       if (((mode &0xc) >> 2) == ucontrol->value.integer.value[0])
+               return 0;
+
+       mode &= 0xfff3;
+       mode |= (ucontrol->value.integer.value[0] << 2);
+
+       wm8753_write(codec, WM8753_IOCTL, mode);
+       wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
+       return 1;
+}
+
+static const struct snd_kcontrol_new wm8753_snd_controls[] = {
+SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0),
+
+SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0),
+
+SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0),
+SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0),
+
+SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0),
+
+SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1),
+SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1),
+SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1),
+
+SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0),
+SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0),
+
+SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1),
+SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1),
+SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 4, 7, 1),
+SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
+
+SOC_ENUM("Bass Boost", wm8753_enum[0]),
+SOC_ENUM("Bass Filter", wm8753_enum[1]),
+SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
+
+SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
+SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
+
+SOC_DOUBLE("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1),
+SOC_SINGLE("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1),
+
+SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0),
+SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
+
+SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
+SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
+SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
+
+SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
+SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
+SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
+SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
+SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
+SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
+SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
+SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
+SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
+SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
+
+SOC_ENUM("3D Function", wm8753_enum[5]),
+SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
+SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
+SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
+SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
+
+SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
+SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
+
+SOC_ENUM("De-emphasis", wm8753_enum[8]),
+SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
+SOC_ENUM("Playback Phase", wm8753_enum[10]),
+
+SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0),
+SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0),
+
+SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
+
+SOC_ENUM("ADC Data Select", wm8753_enum[27]),
+};
+
+/* add non dapm controls */
+static int wm8753_add_controls(struct snd_soc_codec *codec)
+{
+       int err, i;
+
+       for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) {
+               err = snd_ctl_add(codec->card,
+                               snd_soc_cnew(&wm8753_snd_controls[i],codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+/*
+ * _DAPM_ Controls
+ */
+
+/* Left Mixer */
+static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
+};
+
+/* Right mixer */
+static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
+};
+
+/* Mono mixer */
+static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
+};
+
+/* Mono 2 Mux */
+static const struct snd_kcontrol_new wm8753_mono2_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[17]);
+
+/* Out 3 Mux */
+static const struct snd_kcontrol_new wm8753_out3_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[18]);
+
+/* Out 4 Mux */
+static const struct snd_kcontrol_new wm8753_out4_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[19]);
+
+/* ADC Mono Mix */
+static const struct snd_kcontrol_new wm8753_adc_mono_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[22]);
+
+/* Record mixer */
+static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
+SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
+SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
+};
+
+/* Left ADC mux */
+static const struct snd_kcontrol_new wm8753_adc_left_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[21]);
+
+/* Right ADC mux */
+static const struct snd_kcontrol_new wm8753_adc_right_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[20]);
+
+/* MIC mux */
+static const struct snd_kcontrol_new wm8753_mic_mux_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[16]);
+
+/* ALC mixer */
+static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
+SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
+SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
+SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
+};
+
+/* Left Line mux */
+static const struct snd_kcontrol_new wm8753_line_left_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[14]);
+
+/* Right Line mux */
+static const struct snd_kcontrol_new wm8753_line_right_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[13]);
+
+/* Mono Line mux */
+static const struct snd_kcontrol_new wm8753_line_mono_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[12]);
+
+/* Line mux and mixer */
+static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[11]);
+
+/* Rx mux and mixer */
+static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[15]);
+
+/* Mic Selector Mux */
+static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[25]);
+
+static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
+SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
+SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
+       &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
+SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
+SND_SOC_DAPM_OUTPUT("LOUT1"),
+SND_SOC_DAPM_OUTPUT("LOUT2"),
+SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
+       &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
+SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
+SND_SOC_DAPM_OUTPUT("ROUT1"),
+SND_SOC_DAPM_OUTPUT("ROUT2"),
+SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
+       &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
+SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
+SND_SOC_DAPM_OUTPUT("MONO1"),
+SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
+SND_SOC_DAPM_OUTPUT("MONO2"),
+SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0),
+SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
+SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
+SND_SOC_DAPM_OUTPUT("OUT3"),
+SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
+SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
+SND_SOC_DAPM_OUTPUT("OUT4"),
+SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
+       &wm8753_record_mixer_controls[0],
+       ARRAY_SIZE(wm8753_record_mixer_controls)),
+SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
+SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
+       &wm8753_adc_mono_controls),
+SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
+       &wm8753_adc_mono_controls),
+SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_adc_left_controls),
+SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_adc_right_controls),
+SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_mic_mux_controls),
+SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
+       &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
+SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_line_left_controls),
+SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_line_right_controls),
+SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_line_mono_controls),
+SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
+       &wm8753_line_mux_mix_controls),
+SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
+       &wm8753_rx_mux_mix_controls),
+SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
+SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
+       &wm8753_mic_sel_mux_controls),
+SND_SOC_DAPM_INPUT("LINE1"),
+SND_SOC_DAPM_INPUT("LINE2"),
+SND_SOC_DAPM_INPUT("RXP"),
+SND_SOC_DAPM_INPUT("RXN"),
+SND_SOC_DAPM_INPUT("ACIN"),
+SND_SOC_DAPM_OUTPUT("ACOP"),
+SND_SOC_DAPM_INPUT("MIC1N"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2N"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("VREF"),
+};
+
+static const char *audio_map[][3] = {
+       /* left mixer */
+       {"Left Mixer", "Left Playback Switch", "Left DAC"},
+       {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
+       {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+       {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
+
+       /* right mixer */
+       {"Right Mixer", "Right Playback Switch", "Right DAC"},
+       {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
+       {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+       {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
+
+       /* mono mixer */
+       {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
+       {"Mono Mixer", "Left Playback Switch", "Left DAC"},
+       {"Mono Mixer", "Right Playback Switch", "Right DAC"},
+       {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+       {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
+
+       /* left out */
+       {"Left Out 1", NULL, "Left Mixer"},
+       {"Left Out 2", NULL, "Left Mixer"},
+       {"LOUT1", NULL, "Left Out 1"},
+       {"LOUT2", NULL, "Left Out 2"},
+
+       /* right out */
+       {"Right Out 1", NULL, "Right Mixer"},
+       {"Right Out 2", NULL, "Right Mixer"},
+       {"ROUT1", NULL, "Right Out 1"},
+       {"ROUT2", NULL, "Right Out 2"},
+
+       /* mono 1 out */
+       {"Mono Out 1", NULL, "Mono Mixer"},
+       {"MONO1", NULL, "Mono Out 1"},
+
+       /* mono 2 out */
+       {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
+       {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
+       {"Mono 2 Mux", "Left", "Left Mixer"},
+       {"Mono 2 Mux", "Right", "Right Mixer"},
+       {"Mono Out 2", NULL, "Mono 2 Mux"},
+       {"MONO2", NULL, "Mono Out 2"},
+
+       /* out 3 */
+       {"Out3 Left + Right", NULL, "Left Mixer"},
+       {"Out3 Left + Right", NULL, "Right Mixer"},
+       {"Out3 Mux", "VREF", "VREF"},
+       {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
+       {"Out3 Mux", "ROUT2", "ROUT2"},
+       {"Out 3", NULL, "Out3 Mux"},
+       {"OUT3", NULL, "Out 3"},
+
+       /* out 4 */
+       {"Out4 Mux", "VREF", "VREF"},
+       {"Out4 Mux", "Capture ST", "Capture ST Mixer"},
+       {"Out4 Mux", "LOUT2", "LOUT2"},
+       {"Out 4", NULL, "Out4 Mux"},
+       {"OUT4", NULL, "Out 4"},
+
+       /* record mixer  */
+       {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
+       {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
+       {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
+
+       /* Mic/SideTone Mux */
+       {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
+       {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
+       {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
+       {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
+
+       /* Capture Left Mux */
+       {"Capture Left Mux", "PGA", "Left Capture Volume"},
+       {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
+       {"Capture Left Mux", "Line", "LINE1"},
+
+       /* Capture Right Mux */
+       {"Capture Right Mux", "PGA", "Right Capture Volume"},
+       {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
+       {"Capture Right Mux", "Sidetone", "Capture ST Mixer"},
+
+       /* Mono Capture mixer-mux */
+       {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
+       {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
+       {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
+       {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
+       {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
+       {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
+       {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
+       {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
+       {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
+
+       /* ADC */
+       {"Left ADC", NULL, "Capture Left Mixer"},
+       {"Right ADC", NULL, "Capture Right Mixer"},
+
+       /* Left Capture Volume */
+       {"Left Capture Volume", NULL, "ACIN"},
+
+       /* Right Capture Volume */
+       {"Right Capture Volume", NULL, "Mic 2 Volume"},
+
+       /* ALC Mixer */
+       {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
+       {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
+       {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
+       {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
+
+       /* Line Left Mux */
+       {"Line Left Mux", "Line 1", "LINE1"},
+       {"Line Left Mux", "Rx Mix", "Rx Mixer"},
+
+       /* Line Right Mux */
+       {"Line Right Mux", "Line 2", "LINE2"},
+       {"Line Right Mux", "Rx Mix", "Rx Mixer"},
+
+       /* Line Mono Mux */
+       {"Line Mono Mux", "Line Mix", "Line Mixer"},
+       {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
+
+       /* Line Mixer/Mux */
+       {"Line Mixer", "Line 1 + 2", "LINE1"},
+       {"Line Mixer", "Line 1 - 2", "LINE1"},
+       {"Line Mixer", "Line 1 + 2", "LINE2"},
+       {"Line Mixer", "Line 1 - 2", "LINE2"},
+       {"Line Mixer", "Line 1", "LINE1"},
+       {"Line Mixer", "Line 2", "LINE2"},
+
+       /* Rx Mixer/Mux */
+       {"Rx Mixer", "RXP - RXN", "RXP"},
+       {"Rx Mixer", "RXP + RXN", "RXP"},
+       {"Rx Mixer", "RXP - RXN", "RXN"},
+       {"Rx Mixer", "RXP + RXN", "RXN"},
+       {"Rx Mixer", "RXP", "RXP"},
+       {"Rx Mixer", "RXN", "RXN"},
+
+       /* Mic 1 Volume */
+       {"Mic 1 Volume", NULL, "MIC1N"},
+       {"Mic 1 Volume", NULL, "Mic Selection Mux"},
+
+       /* Mic 2 Volume */
+       {"Mic 2 Volume", NULL, "MIC2N"},
+       {"Mic 2 Volume", NULL, "MIC2"},
+
+       /* Mic Selector Mux */
+       {"Mic Selection Mux", "Mic 1", "MIC1"},
+       {"Mic Selection Mux", "Mic 2", "MIC2N"},
+       {"Mic Selection Mux", "Mic 3", "MIC2"},
+
+       /* ACOP */
+       {"ACOP", NULL, "ALC Mixer"},
+
+       /* terminator */
+       {NULL, NULL, NULL},
+};
+
+static int wm8753_add_widgets(struct snd_soc_codec *codec)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++)
+               snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]);
+
+       /* set up the WM8753 audio map */
+       for (i = 0; audio_map[i][0] != NULL; i++) {
+               snd_soc_dapm_connect_input(codec, audio_map[i][0],
+                       audio_map[i][1], audio_map[i][2]);
+       }
+
+       snd_soc_dapm_new_widgets(codec);
+       return 0;
+}
+
+/* PLL divisors */
+struct _pll_div {
+       u32 div2:1;
+       u32 n:4;
+       u32 k:24;
+};
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 22) * 10)
+
+static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+       unsigned int source)
+{
+       u64 Kpart;
+       unsigned int K, Ndiv, Nmod;
+
+       Ndiv = target / source;
+       if (Ndiv < 6) {
+               source >>= 1;
+               pll_div->div2 = 1;
+               Ndiv = target / source;
+       } else
+               pll_div->div2 = 0;
+
+       if ((Ndiv < 6) || (Ndiv > 12))
+               printk(KERN_WARNING
+                       "WM8753 N value outwith recommended range! N = %d\n",Ndiv);
+
+       pll_div->n = Ndiv;
+       Nmod = target % source;
+       Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+       do_div(Kpart, source);
+
+       K = Kpart & 0xFFFFFFFF;
+
+       /* Check if we need to round */
+       if ((K % 10) >= 5)
+               K += 5;
+
+       /* Move down to proper range now rounding is done */
+       K /= 10;
+
+       pll_div->k = K;
+}
+
+static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai,
+               int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+       u16 reg, enable;
+       int offset;
+       struct snd_soc_codec *codec = codec_dai->codec;
+
+       if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
+               return -ENODEV;
+
+       if (pll_id == WM8753_PLL1) {
+               offset = 0;
+               enable = 0x10;
+               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
+       } else {
+               offset = 4;
+               enable = 0x8;
+               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
+       }
+
+       if (!freq_in || !freq_out) {
+               /* disable PLL  */
+               wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
+               wm8753_write(codec, WM8753_CLOCK, reg);
+               return 0;
+       } else {
+               u16 value = 0;
+               struct _pll_div pll_div;
+
+               pll_factors(&pll_div, freq_out * 8, freq_in);
+
+               /* set up N and K PLL divisor ratios */
+               /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
+               value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
+               wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
+
+               /* bits 8:0 = PLL_K[17:9] */
+               value = (pll_div.k & 0x03fe00) >> 9;
+               wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
+
+               /* bits 8:0 = PLL_K[8:0] */
+               value = pll_div.k & 0x0001ff;
+               wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
+
+               /* set PLL as input and enable */
+               wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+                       (pll_div.div2 << 3));
+               wm8753_write(codec, WM8753_CLOCK, reg | enable);
+       }
+       return 0;
+}
+
+struct _coeff_div {
+       u32 mclk;
+       u32 rate;
+       u8 sr:5;
+       u8 usb:1;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+       /* 8k */
+       {12288000, 8000, 0x6, 0x0},
+       {11289600, 8000, 0x16, 0x0},
+       {18432000, 8000, 0x7, 0x0},
+       {16934400, 8000, 0x17, 0x0},
+       {12000000, 8000, 0x6, 0x1},
+
+       /* 11.025k */
+       {11289600, 11025, 0x18, 0x0},
+       {16934400, 11025, 0x19, 0x0},
+       {12000000, 11025, 0x19, 0x1},
+
+       /* 16k */
+       {12288000, 16000, 0xa, 0x0},
+       {18432000, 16000, 0xb, 0x0},
+       {12000000, 16000, 0xa, 0x1},
+
+       /* 22.05k */
+       {11289600, 22050, 0x1a, 0x0},
+       {16934400, 22050, 0x1b, 0x0},
+       {12000000, 22050, 0x1b, 0x1},
+
+       /* 32k */
+       {12288000, 32000, 0xc, 0x0},
+       {18432000, 32000, 0xd, 0x0},
+       {12000000, 32000, 0xa, 0x1},
+
+       /* 44.1k */
+       {11289600, 44100, 0x10, 0x0},
+       {16934400, 44100, 0x11, 0x0},
+       {12000000, 44100, 0x11, 0x1},
+
+       /* 48k */
+       {12288000, 48000, 0x0, 0x0},
+       {18432000, 48000, 0x1, 0x0},
+       {12000000, 48000, 0x0, 0x1},
+
+       /* 88.2k */
+       {11289600, 88200, 0x1e, 0x0},
+       {16934400, 88200, 0x1f, 0x0},
+       {12000000, 88200, 0x1f, 0x1},
+
+       /* 96k */
+       {12288000, 96000, 0xe, 0x0},
+       {18432000, 96000, 0xf, 0x0},
+       {12000000, 96000, 0xe, 0x1},
+};
+
+static int get_coeff(int mclk, int rate)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+               if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+                       return i;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
+               int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct wm8753_priv *wm8753 = codec->private_data;
+
+       switch (freq) {
+       case 11289600:
+       case 12000000:
+       case 12288000:
+       case 16934400:
+       case 18432000:
+               if (clk_id == WM8753_MCLK) {
+                       wm8753->sysclk = freq;
+                       return 0;
+               } else if (clk_id == WM8753_PCMCLK) {
+                       wm8753->pcmclk = freq;
+                       return 0;
+               }
+               break;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Set's ADC and Voice DAC format.
+ */
+static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
+
+       /* interface format */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               voice |= 0x0002;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               voice |= 0x0001;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               voice |= 0x0003;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               voice |= 0x0013;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8753_write(codec, WM8753_PCM, voice);
+       return 0;
+}
+
+/*
+ * Set PCM DAI bit size and sample rate.
+ */
+static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct wm8753_priv *wm8753 = codec->private_data;
+       u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
+       u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
+
+       /* bit size */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               voice |= 0x0004;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               voice |= 0x0008;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               voice |= 0x000c;
+               break;
+       }
+
+       /* sample rate */
+       if (params_rate(params) * 384 == wm8753->pcmclk)
+               srate |= 0x80;
+       wm8753_write(codec, WM8753_SRATE1, srate);
+
+       wm8753_write(codec, WM8753_PCM, voice);
+       return 0;
+}
+
+/*
+ * Set's PCM dai fmt and BCLK.
+ */
+static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 voice, ioctl;
+
+       voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
+       ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               ioctl |= 0x2;
+       case SND_SOC_DAIFMT_CBM_CFS:
+               voice |= 0x0040;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_DSP_A:
+       case SND_SOC_DAIFMT_DSP_B:
+               /* frame inversion not valid for DSP modes */
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       break;
+               case SND_SOC_DAIFMT_IB_NF:
+                       voice |= 0x0080;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case SND_SOC_DAIFMT_I2S:
+       case SND_SOC_DAIFMT_RIGHT_J:
+       case SND_SOC_DAIFMT_LEFT_J:
+               voice &= ~0x0010;
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       break;
+               case SND_SOC_DAIFMT_IB_IF:
+                       voice |= 0x0090;
+                       break;
+               case SND_SOC_DAIFMT_IB_NF:
+                       voice |= 0x0080;
+                       break;
+               case SND_SOC_DAIFMT_NB_IF:
+                       voice |= 0x0010;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8753_write(codec, WM8753_PCM, voice);
+       wm8753_write(codec, WM8753_IOCTL, ioctl);
+       return 0;
+}
+
+static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
+               int div_id, int div)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 reg;
+
+       switch (div_id) {
+       case WM8753_PCMDIV:
+               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
+               wm8753_write(codec, WM8753_CLOCK, reg | div);
+               break;
+       case WM8753_BCLKDIV:
+               reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
+               wm8753_write(codec, WM8753_SRATE2, reg | div);
+               break;
+       case WM8753_VXCLKDIV:
+               reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
+               wm8753_write(codec, WM8753_SRATE2, reg | div);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * Set's HiFi DAC format.
+ */
+static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
+
+       /* interface format */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               hifi |= 0x0002;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               hifi |= 0x0001;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               hifi |= 0x0003;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               hifi |= 0x0013;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8753_write(codec, WM8753_HIFI, hifi);
+       return 0;
+}
+
+/*
+ * Set's I2S DAI format.
+ */
+static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 ioctl, hifi;
+
+       hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
+       ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       case SND_SOC_DAIFMT_CBM_CFM:
+               ioctl |= 0x1;
+       case SND_SOC_DAIFMT_CBM_CFS:
+               hifi |= 0x0040;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_DSP_A:
+       case SND_SOC_DAIFMT_DSP_B:
+               /* frame inversion not valid for DSP modes */
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       break;
+               case SND_SOC_DAIFMT_IB_NF:
+                       hifi |= 0x0080;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case SND_SOC_DAIFMT_I2S:
+       case SND_SOC_DAIFMT_RIGHT_J:
+       case SND_SOC_DAIFMT_LEFT_J:
+               hifi &= ~0x0010;
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       break;
+               case SND_SOC_DAIFMT_IB_IF:
+                       hifi |= 0x0090;
+                       break;
+               case SND_SOC_DAIFMT_IB_NF:
+                       hifi |= 0x0080;
+                       break;
+               case SND_SOC_DAIFMT_NB_IF:
+                       hifi |= 0x0010;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8753_write(codec, WM8753_HIFI, hifi);
+       wm8753_write(codec, WM8753_IOCTL, ioctl);
+       return 0;
+}
+
+/*
+ * Set PCM DAI bit size and sample rate.
+ */
+static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct wm8753_priv *wm8753 = codec->private_data;
+       u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
+       u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
+       int coeff;
+
+       /* is digital filter coefficient valid ? */
+       coeff = get_coeff(wm8753->sysclk, params_rate(params));
+       if (coeff < 0) {
+               printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
+               return coeff;
+       }
+       wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+               coeff_div[coeff].usb);
+
+       /* bit size */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               hifi |= 0x0004;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               hifi |= 0x0008;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               hifi |= 0x000c;
+               break;
+       }
+
+       wm8753_write(codec, WM8753_HIFI, hifi);
+       return 0;
+}
+
+static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 clock;
+
+       /* set clk source as pcmclk */
+       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+       wm8753_write(codec, WM8753_CLOCK, clock);
+
+       if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+               return -EINVAL;
+       return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
+               return -EINVAL;
+       return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 clock;
+
+       /* set clk source as pcmclk */
+       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+       wm8753_write(codec, WM8753_CLOCK, clock);
+
+       if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+               return -EINVAL;
+       return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 clock;
+
+       /* set clk source as mclk */
+       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+       wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
+
+       if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
+               return -EINVAL;
+       if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+               return -EINVAL;
+       return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+
+       /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
+        * make sure we check if they are not both active when we mute */
+       if (mute && dai->id == 1) {
+               if (!wm8753_dai[WM8753_DAI_VOICE].playback.active ||
+                       !wm8753_dai[WM8753_DAI_HIFI].playback.active)
+                       wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+       } else {
+               if (mute)
+                       wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+               else
+                       wm8753_write(codec, WM8753_DAC, mute_reg);
+       }
+
+       return 0;
+}
+
+static int wm8753_dapm_event(struct snd_soc_codec *codec, int event)
+{
+       u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
+
+       switch (event) {
+       case SNDRV_CTL_POWER_D0: /* full On */
+               /* set vmid to 50k and unmute dac */
+               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+               break;
+       case SNDRV_CTL_POWER_D1: /* partial On */
+       case SNDRV_CTL_POWER_D2: /* partial On */
+               /* set vmid to 5k for quick power up */
+               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+               break;
+       case SNDRV_CTL_POWER_D3hot: /* Off, with power */
+               /* mute dac and set vmid to 500k, enable VREF */
+               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+               break;
+       case SNDRV_CTL_POWER_D3cold: /* Off, without power */
+               wm8753_write(codec, WM8753_PWR1, 0x0001);
+               break;
+       }
+       codec->dapm_state = event;
+       return 0;
+}
+
+#define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+               SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
+               SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+       SNDRV_PCM_FMTBIT_S24_LE)
+
+/*
+ * The WM8753 supports upto 4 different and mutually exclusive DAI
+ * configurations. This gives 2 PCM's available for use, hifi and voice.
+ * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
+ * is connected between the wm8753 and a BT codec or GSM modem.
+ *
+ * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
+ * 2. Voice over HIFI DAI - HIFI disabled
+ * 3. Voice disabled - HIFI over HIFI
+ * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
+ */
+static const struct snd_soc_codec_dai wm8753_all_dai[] = {
+/* DAI HiFi mode 1 */
+{      .name = "WM8753 HiFi",
+       .id = 1,
+       .playback = {
+               .stream_name = "HiFi Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .capture = { /* dummy for fast DAI switching */
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .ops = {
+               .hw_params = wm8753_i2s_hw_params,},
+       .dai_ops = {
+               .digital_mute = wm8753_mute,
+               .set_fmt = wm8753_mode1h_set_dai_fmt,
+               .set_clkdiv = wm8753_set_dai_clkdiv,
+               .set_pll = wm8753_set_dai_pll,
+               .set_sysclk = wm8753_set_dai_sysclk,
+       },
+},
+/* DAI Voice mode 1 */
+{      .name = "WM8753 Voice",
+       .id = 1,
+       .playback = {
+               .stream_name = "Voice Playback",
+               .channels_min = 1,
+               .channels_max = 1,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .ops = {
+               .hw_params = wm8753_pcm_hw_params,},
+       .dai_ops = {
+               .digital_mute = wm8753_mute,
+               .set_fmt = wm8753_mode1v_set_dai_fmt,
+               .set_clkdiv = wm8753_set_dai_clkdiv,
+               .set_pll = wm8753_set_dai_pll,
+               .set_sysclk = wm8753_set_dai_sysclk,
+       },
+},
+/* DAI HiFi mode 2 - dummy */
+{      .name = "WM8753 HiFi",
+       .id = 2,
+},
+/* DAI Voice mode 2 */
+{      .name = "WM8753 Voice",
+       .id = 2,
+       .playback = {
+               .stream_name = "Voice Playback",
+               .channels_min = 1,
+               .channels_max = 1,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .ops = {
+               .hw_params = wm8753_pcm_hw_params,},
+       .dai_ops = {
+               .digital_mute = wm8753_mute,
+               .set_fmt = wm8753_mode2_set_dai_fmt,
+               .set_clkdiv = wm8753_set_dai_clkdiv,
+               .set_pll = wm8753_set_dai_pll,
+               .set_sysclk = wm8753_set_dai_sysclk,
+       },
+},
+/* DAI HiFi mode 3 */
+{      .name = "WM8753 HiFi",
+       .id = 3,
+       .playback = {
+               .stream_name = "HiFi Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .ops = {
+               .hw_params = wm8753_i2s_hw_params,},
+       .dai_ops = {
+               .digital_mute = wm8753_mute,
+               .set_fmt = wm8753_mode3_4_set_dai_fmt,
+               .set_clkdiv = wm8753_set_dai_clkdiv,
+               .set_pll = wm8753_set_dai_pll,
+               .set_sysclk = wm8753_set_dai_sysclk,
+       },
+},
+/* DAI Voice mode 3 - dummy */
+{      .name = "WM8753 Voice",
+       .id = 3,
+},
+/* DAI HiFi mode 4 */
+{      .name = "WM8753 HiFi",
+       .id = 4,
+       .playback = {
+               .stream_name = "HiFi Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8753_RATES,
+               .formats = WM8753_FORMATS,},
+       .ops = {
+               .hw_params = wm8753_i2s_hw_params,},
+       .dai_ops = {
+               .digital_mute = wm8753_mute,
+               .set_fmt = wm8753_mode3_4_set_dai_fmt,
+               .set_clkdiv = wm8753_set_dai_clkdiv,
+               .set_pll = wm8753_set_dai_pll,
+               .set_sysclk = wm8753_set_dai_sysclk,
+       },
+},
+/* DAI Voice mode 4 - dummy */
+{      .name = "WM8753 Voice",
+       .id = 4,
+},
+};
+
+struct snd_soc_codec_dai wm8753_dai[2];
+EXPORT_SYMBOL_GPL(wm8753_dai);
+
+static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
+{
+       if (mode < 4) {
+               int playback_active, capture_active, codec_active, pop_wait;
+               void *private_data;
+
+               playback_active = wm8753_dai[0].playback.active;
+               capture_active = wm8753_dai[0].capture.active;
+               codec_active = wm8753_dai[0].active;
+               private_data = wm8753_dai[0].private_data;
+               pop_wait = wm8753_dai[0].pop_wait;
+               wm8753_dai[0] = wm8753_all_dai[mode << 1];
+               wm8753_dai[0].playback.active = playback_active;
+               wm8753_dai[0].capture.active = capture_active;
+               wm8753_dai[0].active = codec_active;
+               wm8753_dai[0].private_data = private_data;
+               wm8753_dai[0].pop_wait = pop_wait;
+
+               playback_active = wm8753_dai[1].playback.active;
+               capture_active = wm8753_dai[1].capture.active;
+               codec_active = wm8753_dai[1].active;
+               private_data = wm8753_dai[1].private_data;
+               pop_wait = wm8753_dai[1].pop_wait;
+               wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
+               wm8753_dai[1].playback.active = playback_active;
+               wm8753_dai[1].capture.active = capture_active;
+               wm8753_dai[1].active = codec_active;
+               wm8753_dai[1].private_data = private_data;
+               wm8753_dai[1].pop_wait = pop_wait;
+       }
+       wm8753_dai[0].codec = codec;
+       wm8753_dai[1].codec = codec;
+}
+
+static void wm8753_work(struct work_struct *work)
+{
+       struct snd_soc_codec *codec =
+               container_of(work, struct snd_soc_codec, delayed_work.work);
+       wm8753_dapm_event(codec, codec->dapm_state);
+}
+
+static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       /* we only need to suspend if we are a valid card */
+       if(!codec->card)
+               return 0;
+               
+       wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+       return 0;
+}
+
+static int wm8753_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+       int i;
+       u8 data[2];
+       u16 *cache = codec->reg_cache;
+
+       /* we only need to resume if we are a valid card */
+       if(!codec->card)
+               return 0;
+
+       /* Sync reg_cache with the hardware */
+       for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
+               if (i + 1 == WM8753_RESET)
+                       continue;
+               data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
+               data[1] = cache[i] & 0x00ff;
+               codec->hw_write(codec->control_data, data, 2);
+       }
+
+       wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+
+       /* charge wm8753 caps */
+       if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) {
+               wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2);
+               codec->dapm_state = SNDRV_CTL_POWER_D0;
+               schedule_delayed_work(&codec->delayed_work,
+                       msecs_to_jiffies(caps_charge));
+       }
+
+       return 0;
+}
+
+/*
+ * initialise the WM8753 driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+static int wm8753_init(struct snd_soc_device *socdev)
+{
+       struct snd_soc_codec *codec = socdev->codec;
+       int reg, ret = 0;
+
+       codec->name = "WM8753";
+       codec->owner = THIS_MODULE;
+       codec->read = wm8753_read_reg_cache;
+       codec->write = wm8753_write;
+       codec->dapm_event = wm8753_dapm_event;
+       codec->dai = wm8753_dai;
+       codec->num_dai = 2;
+       codec->reg_cache_size = sizeof(wm8753_reg);
+       codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL);
+
+       if (codec->reg_cache == NULL)
+               return -ENOMEM;
+
+       wm8753_set_dai_mode(codec, 0);
+
+       wm8753_reset(codec);
+
+       /* register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               printk(KERN_ERR "wm8753: failed to create pcms\n");
+               goto pcm_err;
+       }
+
+       /* charge output caps */
+       wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2);
+       codec->dapm_state = SNDRV_CTL_POWER_D3hot;
+       schedule_delayed_work(&codec->delayed_work,
+               msecs_to_jiffies(caps_charge));
+
+       /* set the update bits */
+       reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
+       wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
+       wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_LADC);
+       wm8753_write(codec, WM8753_LADC, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_RADC);
+       wm8753_write(codec, WM8753_RADC, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
+       wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
+       wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
+       wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
+       wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
+       wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
+       reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
+       wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
+
+       wm8753_add_controls(codec);
+       wm8753_add_widgets(codec);
+       ret = snd_soc_register_card(socdev);
+       if (ret < 0) {
+       printk(KERN_ERR "wm8753: failed to register card\n");
+               goto card_err;
+    }
+       return ret;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+pcm_err:
+       kfree(codec->reg_cache);
+       return ret;
+}
+
+/* If the i2c layer weren't so broken, we could pass this kind of data
+   around */
+static struct snd_soc_device *wm8753_socdev;
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+
+/*
+ * WM8753 2 wire address is determined by GPIO5
+ * state during powerup.
+ *    low  = 0x1a
+ *    high = 0x1b
+ */
+static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
+
+/* Magic definition of all other variables and things */
+I2C_CLIENT_INSMOD;
+
+static struct i2c_driver wm8753_i2c_driver;
+static struct i2c_client client_template;
+
+static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
+{
+       struct snd_soc_device *socdev = wm8753_socdev;
+       struct wm8753_setup_data *setup = socdev->codec_data;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct i2c_client *i2c;
+       int ret;
+
+       if (addr != setup->i2c_address)
+               return -ENODEV;
+
+       client_template.adapter = adap;
+       client_template.addr = addr;
+
+       i2c =  kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
+       if (i2c == NULL){
+               kfree(codec);
+               return -ENOMEM;
+       }
+       i2c_set_clientdata(i2c, codec);
+       codec->control_data = i2c;
+
+       ret = i2c_attach_client(i2c);
+       if (ret < 0) {
+               err("failed to attach codec at addr %x\n", addr);
+               goto err;
+       }
+
+       ret = wm8753_init(socdev);
+       if (ret < 0) {
+               err("failed to initialise WM8753\n");
+               goto err;
+       }
+
+       return ret;
+
+err:
+       kfree(codec);
+       kfree(i2c);
+       return ret;
+}
+
+static int wm8753_i2c_detach(struct i2c_client *client)
+{
+       struct snd_soc_codec *codec = i2c_get_clientdata(client);
+       i2c_detach_client(client);
+       kfree(codec->reg_cache);
+       kfree(client);
+       return 0;
+}
+
+static int wm8753_i2c_attach(struct i2c_adapter *adap)
+{
+       return i2c_probe(adap, &addr_data, wm8753_codec_probe);
+}
+
+/* corgi i2c codec control layer */
+static struct i2c_driver wm8753_i2c_driver = {
+       .driver = {
+               .name = "WM8753 I2C Codec",
+               .owner = THIS_MODULE,
+       },
+       .id =             I2C_DRIVERID_WM8753,
+       .attach_adapter = wm8753_i2c_attach,
+       .detach_client =  wm8753_i2c_detach,
+       .command =        NULL,
+};
+
+static struct i2c_client client_template = {
+       .name =   "WM8753",
+       .driver = &wm8753_i2c_driver,
+};
+#endif
+
+static int wm8753_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct wm8753_setup_data *setup;
+       struct snd_soc_codec *codec;
+       struct wm8753_priv *wm8753;
+       int ret = 0;
+
+       info("WM8753 Audio Codec %s", WM8753_VERSION);
+
+       setup = socdev->codec_data;
+       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+       if (codec == NULL)
+               return -ENOMEM;
+
+       wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
+       if (wm8753 == NULL) {
+               kfree(codec);
+               return -ENOMEM;
+       }
+
+       codec->private_data = wm8753;
+       socdev->codec = codec;
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+       wm8753_socdev = socdev;
+       INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+       if (setup->i2c_address) {
+               normal_i2c[0] = setup->i2c_address;
+               codec->hw_write = (hw_write_t)i2c_master_send;
+               ret = i2c_add_driver(&wm8753_i2c_driver);
+               if (ret != 0)
+                       printk(KERN_ERR "can't add i2c driver");
+       }
+#else
+               /* Add other interfaces here */
+#endif
+       return ret;
+}
+
+/*
+ * This function forces any delayed work to be queued and run.
+ */
+static int run_delayed_work(struct delayed_work *dwork)
+{
+       int ret;
+
+       /* cancel any work waiting to be queued. */
+       ret = cancel_delayed_work(dwork);
+
+       /* if there was any work waiting then we run it now and
+        * wait for it's completion */
+       if (ret) {
+               schedule_delayed_work(dwork, 0);
+               flush_scheduled_work();
+       }
+       return ret;
+}
+
+/* power down chip */
+static int wm8753_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       if (codec->control_data)
+               wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+       run_delayed_work(&codec->delayed_work);
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+       i2c_del_driver(&wm8753_i2c_driver);
+#endif
+       kfree(codec->private_data);
+       kfree(codec);
+
+       return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8753 = {
+       .probe =        wm8753_probe,
+       .remove =       wm8753_remove,
+       .suspend =      wm8753_suspend,
+       .resume =       wm8753_resume,
+};
+
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
+
+MODULE_DESCRIPTION("ASoC WM8753 driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
new file mode 100644 (file)
index 0000000..95e2a1f
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * wm8753.h  --  audio driver for WM8753
+ *
+ * Copyright 2003 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef _WM8753_H
+#define _WM8753_H
+
+/* WM8753 register space */
+
+#define WM8753_DAC             0x01
+#define WM8753_ADC             0x02
+#define WM8753_PCM             0x03
+#define WM8753_HIFI            0x04
+#define WM8753_IOCTL           0x05
+#define WM8753_SRATE1          0x06
+#define WM8753_SRATE2          0x07
+#define WM8753_LDAC            0x08
+#define WM8753_RDAC            0x09
+#define WM8753_BASS            0x0a
+#define WM8753_TREBLE          0x0b
+#define WM8753_ALC1            0x0c
+#define WM8753_ALC2            0x0d
+#define WM8753_ALC3            0x0e
+#define WM8753_NGATE           0x0f
+#define WM8753_LADC            0x10
+#define WM8753_RADC            0x11
+#define WM8753_ADCTL1          0x12
+#define WM8753_3D              0x13
+#define WM8753_PWR1            0x14
+#define WM8753_PWR2            0x15
+#define WM8753_PWR3            0x16
+#define WM8753_PWR4            0x17
+#define WM8753_ID              0x18
+#define WM8753_INTPOL          0x19
+#define WM8753_INTEN           0x1a
+#define WM8753_GPIO1           0x1b
+#define WM8753_GPIO2           0x1c
+#define WM8753_RESET           0x1f
+#define WM8753_RECMIX1         0x20
+#define WM8753_RECMIX2         0x21
+#define WM8753_LOUTM1          0x22
+#define WM8753_LOUTM2          0x23
+#define WM8753_ROUTM1          0x24
+#define WM8753_ROUTM2          0x25
+#define WM8753_MOUTM1          0x26
+#define WM8753_MOUTM2          0x27
+#define WM8753_LOUT1V          0x28
+#define WM8753_ROUT1V          0x29
+#define WM8753_LOUT2V          0x2a
+#define WM8753_ROUT2V          0x2b
+#define WM8753_MOUTV           0x2c
+#define WM8753_OUTCTL          0x2d
+#define WM8753_ADCIN           0x2e
+#define WM8753_INCTL1          0x2f
+#define WM8753_INCTL2          0x30
+#define WM8753_LINVOL          0x31
+#define WM8753_RINVOL          0x32
+#define WM8753_MICBIAS         0x33
+#define WM8753_CLOCK           0x34
+#define WM8753_PLL1CTL1                0x35
+#define WM8753_PLL1CTL2                0x36
+#define WM8753_PLL1CTL3                0x37
+#define WM8753_PLL1CTL4                0x38
+#define WM8753_PLL2CTL1                0x39
+#define WM8753_PLL2CTL2                0x3a
+#define WM8753_PLL2CTL3                0x3b
+#define WM8753_PLL2CTL4                0x3c
+#define WM8753_BIASCTL         0x3d
+#define WM8753_ADCTL2          0x3f
+
+struct wm8753_setup_data {
+       unsigned short i2c_address;
+};
+
+#define WM8753_PLL1                    0
+#define WM8753_PLL2                    1
+
+/* clock inputs */
+#define WM8753_MCLK            0
+#define WM8753_PCMCLK          1
+
+/* clock divider id's */
+#define WM8753_PCMDIV          0
+#define WM8753_BCLKDIV         1
+#define WM8753_VXCLKDIV                2
+
+/* PCM clock dividers */
+#define WM8753_PCM_DIV_1       (0 << 6)
+#define WM8753_PCM_DIV_3       (2 << 6)
+#define WM8753_PCM_DIV_5_5     (3 << 6)
+#define WM8753_PCM_DIV_2       (4 << 6)
+#define WM8753_PCM_DIV_4       (5 << 6)
+#define WM8753_PCM_DIV_6       (6 << 6)
+#define WM8753_PCM_DIV_8       (7 << 6)
+
+/* BCLK clock dividers */
+#define WM8753_BCLK_DIV_1      (0 << 3)
+#define WM8753_BCLK_DIV_2      (1 << 3)
+#define WM8753_BCLK_DIV_4      (2 << 3)
+#define WM8753_BCLK_DIV_8      (3 << 3)
+#define WM8753_BCLK_DIV_16     (4 << 3)
+
+/* VXCLK clock dividers */
+#define WM8753_VXCLK_DIV_1     (0 << 6)
+#define WM8753_VXCLK_DIV_2     (1 << 6)
+#define WM8753_VXCLK_DIV_4     (2 << 6)
+#define WM8753_VXCLK_DIV_8     (3 << 6)
+#define WM8753_VXCLK_DIV_16    (4 << 6)
+
+#define WM8753_DAI_HIFI                0
+#define WM8753_DAI_VOICE               1
+
+extern struct snd_soc_codec_dai wm8753_dai[2];
+extern struct snd_soc_codec_device soc_codec_dev_wm8753;
+
+#endif
index ee7a691a9ba163b0fff87a07aad33ea3cf9d84ca..264413a00cac530b907b2e1959a893f0dde8d4d7 100644 (file)
@@ -676,14 +676,13 @@ static int wm9712_soc_probe(struct platform_device *pdev)
        codec = socdev->codec;
        mutex_init(&codec->mutex);
 
-       codec->reg_cache =
-               kzalloc(sizeof(u16) * ARRAY_SIZE(wm9712_reg), GFP_KERNEL);
+       codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
+
        if (codec->reg_cache == NULL) {
                ret = -ENOMEM;
                goto cache_err;
        }
-       memcpy(codec->reg_cache, wm9712_reg, sizeof(u16) * ARRAY_SIZE(wm9712_reg));
-       codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9712_reg);
+       codec->reg_cache_size = sizeof(wm9712_reg);
        codec->reg_cache_step = 2;
 
        codec->name = "WM9712";
index b9ab3b8e1d3ecdff0aec3ec1823e1c6f3f5e19dd..a83e22937c270ce0d92720203d73de99f8d1e434 100644 (file)
@@ -1,5 +1,3 @@
-menu "SoC Audio for the Intel PXA2xx"
-
 config SND_PXA2XX_SOC
        tristate "SoC Audio for the Intel PXA2xx chip"
        depends on ARCH_PXA && SND_SOC
@@ -55,5 +53,3 @@ config SND_PXA2XX_SOC_TOSA
        help
          Say Y if you want to add support for SoC audio on Sharp
          Zaurus SL-C6000x models (Tosa).
-
-endmenu
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
new file mode 100644 (file)
index 0000000..044a371
--- /dev/null
@@ -0,0 +1,10 @@
+config SND_S3C24XX_SOC
+       tristate "SoC Audio for the Samsung S3C24XX chips"
+       depends on ARCH_S3C2410 && SND_SOC
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the S3C24XX AC97, I2S or SSP interface. You will also need
+         to select the audio interfaces to support below.
+
+config SND_S3C24XX_SOC_I2S
+       tristate
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
new file mode 100644 (file)
index 0000000..6f0fffc
--- /dev/null
@@ -0,0 +1,6 @@
+# S3c24XX Platform Support
+snd-soc-s3c24xx-objs := s3c24xx-pcm.o
+snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
+
+obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
+obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
new file mode 100644 (file)
index 0000000..8ca314d
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * s3c24xx-i2s.c  --  ALSA Soc Audio Layer
+ *
+ * (c) 2006 Wolfson Microelectronics PLC.
+ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  Revision history
+ *    11th Dec 2006   Merged with Simtec driver
+ *    10th Nov 2006   Initial version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/audio.h>
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+
+#include "s3c24xx-pcm.h"
+#include "s3c24xx-i2s.h"
+
+#define S3C24XX_I2S_DEBUG 0
+#if S3C24XX_I2S_DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+static struct s3c2410_dma_client s3c24xx_dma_client_out = {
+       .name = "I2S PCM Stereo out"
+};
+
+static struct s3c2410_dma_client s3c24xx_dma_client_in = {
+       .name = "I2S PCM Stereo in"
+};
+
+static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = {
+       .client         = &s3c24xx_dma_client_out,
+       .channel        = DMACH_I2S_OUT,
+       .dma_addr       = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       .dma_size       = 2,
+};
+
+static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = {
+       .client         = &s3c24xx_dma_client_in,
+       .channel        = DMACH_I2S_IN,
+       .dma_addr       = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       .dma_size       = 2,
+};
+
+struct s3c24xx_i2s_info {
+       void __iomem    *regs;
+       struct clk      *iis_clk;
+};
+static struct s3c24xx_i2s_info s3c24xx_i2s;
+
+static void s3c24xx_snd_txctrl(int on)
+{
+       u32 iisfcon;
+       u32 iiscon;
+       u32 iismod;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
+       iiscon  = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+       iismod  = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+       DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+
+       if (on) {
+               iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE;
+               iiscon  |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN;
+               iiscon  &= ~S3C2410_IISCON_TXIDLE;
+               iismod  |= S3C2410_IISMOD_TXMODE;
+
+               writel(iismod,  s3c24xx_i2s.regs + S3C2410_IISMOD);
+               writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+               writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
+       } else {
+               /* note, we have to disable the FIFOs otherwise bad things
+                * seem to happen when the DMA stops. According to the
+                * Samsung supplied kernel, this should allow the DMA
+                * engine and FIFOs to reset. If this isn't allowed, the
+                * DMA engine will simply freeze randomly.
+                */
+
+               iisfcon &= ~S3C2410_IISFCON_TXENABLE;
+               iisfcon &= ~S3C2410_IISFCON_TXDMA;
+               iiscon  |=  S3C2410_IISCON_TXIDLE;
+               iiscon  &= ~S3C2410_IISCON_TXDMAEN;
+               iismod  &= ~S3C2410_IISMOD_TXMODE;
+
+               writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
+               writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+               writel(iismod,  s3c24xx_i2s.regs + S3C2410_IISMOD);
+       }
+
+       DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+}
+
+static void s3c24xx_snd_rxctrl(int on)
+{
+       u32 iisfcon;
+       u32 iiscon;
+       u32 iismod;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
+       iiscon  = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+       iismod  = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+       DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+
+       if (on) {
+               iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE;
+               iiscon  |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN;
+               iiscon  &= ~S3C2410_IISCON_RXIDLE;
+               iismod  |= S3C2410_IISMOD_RXMODE;
+
+               writel(iismod,  s3c24xx_i2s.regs + S3C2410_IISMOD);
+               writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+               writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
+       } else {
+               /* note, we have to disable the FIFOs otherwise bad things
+                * seem to happen when the DMA stops. According to the
+                * Samsung supplied kernel, this should allow the DMA
+                * engine and FIFOs to reset. If this isn't allowed, the
+                * DMA engine will simply freeze randomly.
+                */
+
+        iisfcon &= ~S3C2410_IISFCON_RXENABLE;
+        iisfcon &= ~S3C2410_IISFCON_RXDMA;
+        iiscon  |= S3C2410_IISCON_RXIDLE;
+        iiscon  &= ~S3C2410_IISCON_RXDMAEN;
+               iismod  &= ~S3C2410_IISMOD_RXMODE;
+
+               writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+               writel(iiscon,  s3c24xx_i2s.regs + S3C2410_IISCON);
+               writel(iismod,  s3c24xx_i2s.regs + S3C2410_IISMOD);
+       }
+
+       DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+}
+
+/*
+ * Wait for the LR signal to allow synchronisation to the L/R clock
+ * from the codec. May only be needed for slave mode.
+ */
+static int s3c24xx_snd_lrsync(void)
+{
+       u32 iiscon;
+       unsigned long timeout = jiffies + msecs_to_jiffies(5);
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       while (1) {
+               iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+               if (iiscon & S3C2410_IISCON_LRINDEX)
+                       break;
+
+               if (timeout < jiffies)
+                       return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+/*
+ * Check whether CPU is the master or slave
+ */
+static inline int s3c24xx_snd_is_clkmaster(void)
+{
+       DBG("Entered %s\n", __FUNCTION__);
+
+       return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1;
+}
+
+/*
+ * Set S3C24xx I2S DAI format
+ */
+static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai,
+               unsigned int fmt)
+{
+       u32 iismod;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+       DBG("hw_params r: IISMOD: %lx \n", iismod);
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               iismod |= S3C2410_IISMOD_SLAVE;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_LEFT_J:
+               iismod |= S3C2410_IISMOD_MSB;
+               break;
+       case SND_SOC_DAIFMT_I2S:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+       DBG("hw_params w: IISMOD: %lx \n", iismod);
+       return 0;
+}
+
+static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       u32 iismod;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+       else
+               rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+       /* Working copies of register */
+       iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+       DBG("hw_params r: IISMOD: %lx\n", iismod);
+
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S8:
+               break;
+       case SNDRV_PCM_FORMAT_S16_LE:
+               iismod |= S3C2410_IISMOD_16BIT;
+               break;
+       }
+
+       writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+       DBG("hw_params w: IISMOD: %lx\n", iismod);
+       return 0;
+}
+
+static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       int ret = 0;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               if (!s3c24xx_snd_is_clkmaster()) {
+                       ret = s3c24xx_snd_lrsync();
+                       if (ret)
+                               goto exit_err;
+               }
+
+               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+                       s3c24xx_snd_rxctrl(1);
+               else
+                       s3c24xx_snd_txctrl(1);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+                       s3c24xx_snd_rxctrl(0);
+               else
+                       s3c24xx_snd_txctrl(0);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+exit_err:
+       return ret;
+}
+
+/*
+ * Set S3C24xx Clock source
+ */
+static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
+       int clk_id, unsigned int freq, int dir)
+{
+       u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       iismod &= ~S3C2440_IISMOD_MPLL;
+
+       switch (clk_id) {
+       case S3C24XX_CLKSRC_PCLK:
+               break;
+       case S3C24XX_CLKSRC_MPLL:
+               iismod |= S3C2440_IISMOD_MPLL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+       return 0;
+}
+
+/*
+ * Set S3C24xx Clock dividers
+ */
+static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
+       int div_id, int div)
+{
+       u32 reg;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       switch (div_id) {
+       case S3C24XX_DIV_MCLK:
+               reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK;
+               writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
+               break;
+       case S3C24XX_DIV_BCLK:
+               reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS);
+               writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
+               break;
+       case S3C24XX_DIV_PRESCALER:
+               writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR);
+               reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+               writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * To avoid duplicating clock code, allow machine driver to
+ * get the clockrate from here.
+ */
+u32 s3c24xx_i2s_get_clockrate(void)
+{
+       return clk_get_rate(s3c24xx_i2s.iis_clk);
+}
+EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
+
+static int s3c24xx_i2s_probe(struct platform_device *pdev)
+{
+       DBG("Entered %s\n", __FUNCTION__);
+
+       s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
+       if (s3c24xx_i2s.regs == NULL)
+               return -ENXIO;
+
+       s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis");
+       if (s3c24xx_i2s.iis_clk == NULL) {
+               DBG("failed to get iis_clock\n");
+               return -ENODEV;
+       }
+       clk_enable(s3c24xx_i2s.iis_clk);
+
+       /* Configure the I2S pins in correct mode */
+       s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
+       s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
+       s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
+       s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
+       s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
+
+       writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
+
+       s3c24xx_snd_txctrl(0);
+       s3c24xx_snd_rxctrl(0);
+
+       return 0;
+}
+
+#define S3C24XX_I2S_RATES \
+       (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+       SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+struct snd_soc_cpu_dai s3c24xx_i2s_dai = {
+       .name = "s3c24xx-i2s",
+       .id = 0,
+       .type = SND_SOC_DAI_I2S,
+       .probe = s3c24xx_i2s_probe,
+       .playback = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = S3C24XX_I2S_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = S3C24XX_I2S_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
+       .ops = {
+               .trigger = s3c24xx_i2s_trigger,
+               .hw_params = s3c24xx_i2s_hw_params,},
+       .dai_ops = {
+               .set_fmt = s3c24xx_i2s_set_fmt,
+               .set_clkdiv = s3c24xx_i2s_set_clkdiv,
+               .set_sysclk = s3c24xx_i2s_set_sysclk,
+       },
+};
+EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
+
+/* Module information */
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h
new file mode 100644 (file)
index 0000000..537b4ec
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * s3c24xx-i2s.c  --  ALSA Soc Audio Layer
+ *
+ * Copyright 2005 Wolfson Microelectronics PLC.
+ * Author: Graeme Gregory
+ *         graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  Revision history
+ *    10th Nov 2006   Initial version.
+ */
+
+#ifndef S3C24XXI2S_H_
+#define S3C24XXI2S_H_
+
+/* clock sources */
+#define S3C24XX_CLKSRC_PCLK 0
+#define S3C24XX_CLKSRC_MPLL 1
+
+/* Clock dividers */
+#define S3C24XX_DIV_MCLK       0
+#define S3C24XX_DIV_BCLK       1
+#define S3C24XX_DIV_PRESCALER  2
+
+/* prescaler */
+#define S3C24XX_PRESCALE(a,b) \
+       (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT))
+
+u32 s3c24xx_i2s_get_clockrate(void);
+
+extern struct snd_soc_cpu_dai s3c24xx_i2s_dai;
+
+#endif /*S3C24XXI2S_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
new file mode 100644 (file)
index 0000000..21dc697
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * s3c24xx-pcm.c  --  ALSA Soc Audio Layer
+ *
+ * (c) 2006 Wolfson Microelectronics PLC.
+ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  Revision history
+ *    11th Dec 2006   Merged with Simtec driver
+ *    10th Nov 2006   Initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/audio.h>
+
+#include "s3c24xx-pcm.h"
+
+#define S3C24XX_PCM_DEBUG 0
+#if S3C24XX_PCM_DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+static const struct snd_pcm_hardware s3c24xx_pcm_hardware = {
+       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
+                                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                   SNDRV_PCM_INFO_MMAP |
+                                   SNDRV_PCM_INFO_MMAP_VALID,
+       .formats                = SNDRV_PCM_FMTBIT_S16_LE |
+                                   SNDRV_PCM_FMTBIT_U16_LE |
+                                   SNDRV_PCM_FMTBIT_U8 |
+                                   SNDRV_PCM_FMTBIT_S8,
+       .channels_min           = 2,
+       .channels_max           = 2,
+       .buffer_bytes_max       = 128*1024,
+       .period_bytes_min       = PAGE_SIZE,
+       .period_bytes_max       = PAGE_SIZE*2,
+       .periods_min            = 2,
+       .periods_max            = 128,
+       .fifo_size              = 32,
+};
+
+struct s3c24xx_runtime_data {
+       spinlock_t lock;
+       int state;
+       unsigned int dma_loaded;
+       unsigned int dma_limit;
+       unsigned int dma_period;
+       dma_addr_t dma_start;
+       dma_addr_t dma_pos;
+       dma_addr_t dma_end;
+       struct s3c24xx_pcm_dma_params *params;
+};
+
+/* s3c24xx_pcm_enqueue
+ *
+ * place a dma buffer onto the queue for the dma system
+ * to handle.
+*/
+static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
+{
+       struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+       dma_addr_t pos = prtd->dma_pos;
+       int ret;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       while (prtd->dma_loaded < prtd->dma_limit) {
+               unsigned long len = prtd->dma_period;
+
+               DBG("dma_loaded: %d\n",prtd->dma_loaded);
+
+               if ((pos + len) > prtd->dma_end) {
+                       len  = prtd->dma_end - pos;
+                       DBG(KERN_DEBUG "%s: corrected dma len %ld\n",
+                              __FUNCTION__, len);
+               }
+
+               ret = s3c2410_dma_enqueue(prtd->params->channel, 
+                       substream, pos, len);
+
+               if (ret == 0) {
+                       prtd->dma_loaded++;
+                       pos += prtd->dma_period;
+                       if (pos >= prtd->dma_end)
+                               pos = prtd->dma_start;
+               } else
+                       break;
+       }
+
+       prtd->dma_pos = pos;
+}
+
+static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
+                               void *dev_id, int size,
+                               enum s3c2410_dma_buffresult result)
+{
+       struct snd_pcm_substream *substream = dev_id;
+       struct s3c24xx_runtime_data *prtd;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR)
+               return;
+
+       prtd = substream->runtime->private_data;
+       
+       if (substream)
+               snd_pcm_period_elapsed(substream);
+
+       spin_lock(&prtd->lock);
+       if (prtd->state & ST_RUNNING) {
+               prtd->dma_loaded--;
+               s3c24xx_pcm_enqueue(substream);
+       }
+
+       spin_unlock(&prtd->lock);
+}
+
+static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct s3c24xx_runtime_data *prtd = runtime->private_data;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+       unsigned long totbytes = params_buffer_bytes(params);
+       int ret=0;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       /* return if this is a bufferless transfer e.g.
+        * codec <--> BT codec or GSM modem -- lg FIXME */
+       if (!dma)
+               return 0;
+
+       /* prepare DMA */
+       prtd->params = dma;
+
+       DBG("params %p, client %p, channel %d\n", prtd->params,
+               prtd->params->client, prtd->params->channel);
+
+       ret = s3c2410_dma_request(prtd->params->channel,
+                                 prtd->params->client, NULL);
+
+       if (ret) {
+               DBG(KERN_ERR "failed to get dma channel\n");
+               return ret;
+       }
+
+       /* channel needs configuring for mem=>device, increment memory addr,
+        * sync to pclk, half-word transfers to the IIS-FIFO. */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               s3c2410_dma_devconfig(prtd->params->channel,
+                               S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC |
+                               S3C2410_DISRCC_APB, prtd->params->dma_addr);
+
+               s3c2410_dma_config(prtd->params->channel,
+                               prtd->params->dma_size,
+                               S3C2410_DCON_SYNC_PCLK | 
+                               S3C2410_DCON_HANDSHAKE);
+       } else {
+               s3c2410_dma_config(prtd->params->channel,
+                               prtd->params->dma_size,
+                               S3C2410_DCON_HANDSHAKE | 
+                               S3C2410_DCON_SYNC_PCLK);
+
+               s3c2410_dma_devconfig(prtd->params->channel,
+                                       S3C2410_DMASRC_HW, 0x3,
+                                       prtd->params->dma_addr);
+       }
+
+       s3c2410_dma_set_buffdone_fn(prtd->params->channel,
+                                   s3c24xx_audio_buffdone);
+
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+       runtime->dma_bytes = totbytes;
+
+       spin_lock_irq(&prtd->lock);
+       prtd->dma_loaded = 0;
+       prtd->dma_limit = runtime->hw.periods_min;
+       prtd->dma_period = params_period_bytes(params);
+       prtd->dma_start = runtime->dma_addr;
+       prtd->dma_pos = prtd->dma_start;
+       prtd->dma_end = prtd->dma_start + totbytes;
+       spin_unlock_irq(&prtd->lock);
+
+       return 0;
+}
+
+static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       /* TODO - do we need to ensure DMA flushed */
+       snd_pcm_set_runtime_buffer(substream, NULL);
+
+       if (prtd->params) {
+               s3c2410_dma_free(prtd->params->channel, prtd->params->client);
+               prtd->params = NULL;
+       }
+
+       return 0;
+}
+
+static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+       int ret = 0;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       /* return if this is a bufferless transfer e.g.
+        * codec <--> BT codec or GSM modem -- lg FIXME */
+       if (!prtd->params)
+               return 0;
+
+       /* flush the DMA channel */
+       s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+       prtd->dma_loaded = 0;
+       prtd->dma_pos = prtd->dma_start;
+
+       /* enqueue dma buffers */
+       s3c24xx_pcm_enqueue(substream);
+
+       return ret;
+}
+
+static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+       int ret = 0;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       spin_lock(&prtd->lock);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               prtd->state |= ST_RUNNING;
+               s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
+               s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
+               break;
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               prtd->state &= ~ST_RUNNING;
+               s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       spin_unlock(&prtd->lock);
+
+       return ret;
+}
+
+static snd_pcm_uframes_t 
+       s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct s3c24xx_runtime_data *prtd = runtime->private_data;
+       unsigned long res;
+       dma_addr_t src, dst;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       spin_lock(&prtd->lock);
+       s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
+
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               res = dst - prtd->dma_start;
+       else
+               res = src - prtd->dma_start;
+
+       spin_unlock(&prtd->lock);
+
+       DBG("Pointer %x %x\n",src,dst);
+
+       /* we seem to be getting the odd error from the pcm library due
+        * to out-of-bounds pointers. this is maybe due to the dma engine
+        * not having loaded the new values for the channel before being
+        * callled... (todo - fix )
+        */
+
+       if (res >= snd_pcm_lib_buffer_bytes(substream)) {
+               if (res == snd_pcm_lib_buffer_bytes(substream))
+                       res = 0;
+       }
+
+       return bytes_to_frames(substream->runtime, res);
+}
+
+static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct s3c24xx_runtime_data *prtd;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);
+
+       prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+       if (prtd == NULL)
+               return -ENOMEM;
+
+       runtime->private_data = prtd;
+       return 0;
+}
+
+static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct s3c24xx_runtime_data *prtd = runtime->private_data;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       if (prtd)
+               kfree(prtd);
+       else
+               DBG("s3c24xx_pcm_close called with prtd == NULL\n");
+
+       return 0;
+}
+
+static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
+       struct vm_area_struct *vma)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+                                     runtime->dma_area,
+                                     runtime->dma_addr,
+                                     runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops s3c24xx_pcm_ops = {
+       .open           = s3c24xx_pcm_open,
+       .close          = s3c24xx_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = s3c24xx_pcm_hw_params,
+       .hw_free        = s3c24xx_pcm_hw_free,
+       .prepare        = s3c24xx_pcm_prepare,
+       .trigger        = s3c24xx_pcm_trigger,
+       .pointer        = s3c24xx_pcm_pointer,
+       .mmap           = s3c24xx_pcm_mmap,
+};
+
+static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+       struct snd_dma_buffer *buf = &substream->dma_buffer;
+       size_t size = s3c24xx_pcm_hardware.buffer_bytes_max;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       buf->dev.type = SNDRV_DMA_TYPE_DEV;
+       buf->dev.dev = pcm->card->dev;
+       buf->private_data = NULL;
+       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+                                          &buf->addr, GFP_KERNEL);
+       if (!buf->area)
+               return -ENOMEM;
+       buf->bytes = size;
+       return 0;
+}
+
+static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_dma_buffer *buf;
+       int stream;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       for (stream = 0; stream < 2; stream++) {
+               substream = pcm->streams[stream].substream;
+               if (!substream)
+                       continue;
+
+               buf = &substream->dma_buffer;
+               if (!buf->area)
+                       continue;
+
+               dma_free_writecombine(pcm->card->dev, buf->bytes,
+                                     buf->area, buf->addr);
+               buf->area = NULL;
+       }
+}
+
+static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK;
+
+static int s3c24xx_pcm_new(struct snd_card *card, 
+       struct snd_soc_codec_dai *dai, struct snd_pcm *pcm)
+{
+       int ret = 0;
+
+       DBG("Entered %s\n", __FUNCTION__);
+
+       if (!card->dev->dma_mask)
+               card->dev->dma_mask = &s3c24xx_pcm_dmamask;
+       if (!card->dev->coherent_dma_mask)
+               card->dev->coherent_dma_mask = 0xffffffff;
+
+       if (dai->playback.channels_min) {
+               ret = s3c24xx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (dai->capture.channels_min) {
+               ret = s3c24xx_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+ out:
+       return ret;
+}
+
+struct snd_soc_platform s3c24xx_soc_platform = {
+       .name           = "s3c24xx-audio",
+       .pcm_ops        = &s3c24xx_pcm_ops,
+       .pcm_new        = s3c24xx_pcm_new,
+       .pcm_free       = s3c24xx_pcm_free_dma_buffers,
+};
+
+EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
+
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h
new file mode 100644 (file)
index 0000000..0088c79
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  s3c24xx-pcm.h --
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  ALSA PCM interface for the Samsung S3C24xx CPU
+ */
+
+#ifndef _S3C24XX_PCM_H
+#define _S3C24XX_PCM_H
+
+#define ST_RUNNING             (1<<0)
+#define ST_OPENED              (1<<1)
+
+struct s3c24xx_pcm_dma_params {
+       struct s3c2410_dma_client *client;      /* stream identifier */
+       int channel;                            /* Channel ID */
+       dma_addr_t dma_addr;
+       int dma_size;                   /* Size of the DMA transfer */
+};
+
+#define S3C24XX_DAI_I2S                        0
+
+/* platform data */
+extern struct snd_soc_platform s3c24xx_soc_platform;
+extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
+
+#endif
index 7caf8c7b0ac5063c14a20784011de0951047e5c9..96bce55572a040ce05d665af500b8aa800dc3c04 100644 (file)
@@ -882,13 +882,15 @@ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
        if (wsink->id == snd_soc_dapm_input) {
                if (wsource->id == snd_soc_dapm_micbias ||
                        wsource->id == snd_soc_dapm_mic ||
-                       wsink->id == snd_soc_dapm_line)
+                       wsink->id == snd_soc_dapm_line ||
+                       wsink->id == snd_soc_dapm_output)
                        wsink->ext = 1;
        }
        if (wsource->id == snd_soc_dapm_output) {
                if (wsink->id == snd_soc_dapm_spk ||
                        wsink->id == snd_soc_dapm_hp ||
-                       wsink->id == snd_soc_dapm_line)
+                       wsink->id == snd_soc_dapm_line ||
+                       wsink->id == snd_soc_dapm_input)
                        wsource->ext = 1;
        }
 
index 900a00de35fd7b016f0e10b7bbfa9dd2db2a5ae9..dca0344cc1bc393734a06d6eb0e71b8a634238b3 100644 (file)
@@ -661,11 +661,9 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
        {
                unsigned int what = 0;
                struct snd_pcm_substream *s;
-               struct list_head *pos;
                unsigned long flags;
 
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
+               snd_pcm_group_for_each_entry(s, substream) {
                        if (s == chip->playback_substream) {
                                what |= CS4231_PLAYBACK_ENABLE;
                                snd_pcm_trigger_done(s, substream);
index f05d02f5b69f9233aca85c8927446db08b2fd27e..315360f312787cd0ef116a33d6af9ebd51b5fc07 100644 (file)
@@ -29,5 +29,33 @@ config SND_USB_USX2Y
          To compile this driver as a module, choose M here: the module
          will be called snd-usb-usx2y.
 
+config SND_USB_CAIAQ
+       tristate "Native Instruments USB audio devices"
+        depends on SND && USB
+        select SND_HWDEP
+        select SND_RAWMIDI
+        select SND_PCM
+        help
+          Say Y here to include support for caiaq USB audio interfaces,
+          namely:
+
+           * Native Instruments RigKontrol2
+           * Native Instruments Kore Controller
+           * Native Instruments Audio Kontrol 1
+           * Native Instruments Audio 8 DJ
+
+          To compile this driver as a module, choose M here: the module
+          will be called snd-usb-caiaq.
+
+config SND_USB_CAIAQ_INPUT
+       bool "enable input device for controllers"
+       depends on SND_USB_CAIAQ
+       help
+         Say Y here to support input controllers like buttons, knobs,
+         alpha dials and analog pedals on the following products:
+
+          * Native Instruments RigKontrol2
+          * Native Instruments Audio Kontrol 1
+
 endmenu
 
index 2c1dc11a72e2f979d3f864c21a1db203f97c6d37..aa252ef2ebfbd3ab81da82a89f7883ac49132190 100644 (file)
@@ -9,4 +9,4 @@ snd-usb-lib-objs := usbmidi.o
 obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
 obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
 
-obj-$(CONFIG_SND) += usx2y/
+obj-$(CONFIG_SND) += usx2y/ caiaq/
diff --git a/sound/usb/caiaq/Makefile b/sound/usb/caiaq/Makefile
new file mode 100644 (file)
index 0000000..455c8c5
--- /dev/null
@@ -0,0 +1,3 @@
+snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o
+
+obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c
new file mode 100644 (file)
index 0000000..0414d76
--- /dev/null
@@ -0,0 +1,707 @@
+/*
+ *   Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/spinlock.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+#include <linux/input.h>
+#endif
+
+#include "caiaq-device.h"
+#include "caiaq-audio.h"
+
+#define N_URBS                 32
+#define CLOCK_DRIFT_TOLERANCE  5
+#define FRAMES_PER_URB         8
+#define BYTES_PER_FRAME                512
+#define CHANNELS_PER_STREAM    2
+#define BYTES_PER_SAMPLE       3
+#define BYTES_PER_SAMPLE_USB   4
+#define MAX_BUFFER_SIZE                (128*1024)
+                                
+#define ENDPOINT_CAPTURE       2
+#define ENDPOINT_PLAYBACK      6
+
+#define MAKE_CHECKBYTE(dev,stream,i) \
+       (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
+
+static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
+       .info           = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 
+                          SNDRV_PCM_INFO_BLOCK_TRANSFER),
+       .formats        = SNDRV_PCM_FMTBIT_S24_3BE,
+       .rates          = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 
+                          SNDRV_PCM_RATE_96000),
+       .rate_min       = 44100,
+       .rate_max       = 0, /* will overwrite later */
+       .channels_min   = CHANNELS_PER_STREAM,
+       .channels_max   = CHANNELS_PER_STREAM,
+       .buffer_bytes_max = MAX_BUFFER_SIZE,
+       .period_bytes_min = 4096,
+       .period_bytes_max = MAX_BUFFER_SIZE,
+       .periods_min    = 1,
+       .periods_max    = 1024,
+};
+
+static void
+activate_substream(struct snd_usb_caiaqdev *dev,
+                  struct snd_pcm_substream *sub)
+{
+       if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dev->sub_playback[sub->number] = sub;
+       else
+               dev->sub_capture[sub->number] = sub;
+}
+
+static void 
+deactivate_substream(struct snd_usb_caiaqdev *dev,
+                    struct snd_pcm_substream *sub)
+{
+       if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dev->sub_playback[sub->number] = NULL;
+       else
+               dev->sub_capture[sub->number] = NULL;
+}
+
+static int
+all_substreams_zero(struct snd_pcm_substream **subs)
+{
+       int i;
+       for (i = 0; i < MAX_STREAMS; i++)
+               if (subs[i] != NULL)
+                       return 0;
+       return 1;
+}
+
+static int stream_start(struct snd_usb_caiaqdev *dev)
+{
+       int i, ret;
+
+       debug("stream_start(%p)\n", dev);
+       spin_lock_irq(&dev->spinlock);
+       if (dev->streaming) {
+               spin_unlock_irq(&dev->spinlock);
+               return -EINVAL;
+       }
+
+       dev->input_panic = 0;
+       dev->output_panic = 0;
+       dev->first_packet = 1;
+       dev->streaming = 1;
+
+       for (i = 0; i < N_URBS; i++) {
+               ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
+               if (ret) {
+                       log("unable to trigger initial read #%d! (ret = %d)\n",
+                               i, ret);
+                       dev->streaming = 0;
+                       spin_unlock_irq(&dev->spinlock);
+                       return -EPIPE;
+               }
+       }
+       
+       spin_unlock_irq(&dev->spinlock);
+       return 0;
+}
+
+static void stream_stop(struct snd_usb_caiaqdev *dev)
+{
+       int i;
+       
+       debug("stream_stop(%p)\n", dev);
+       if (!dev->streaming)
+               return;
+       
+       dev->streaming = 0;
+       for (i = 0; i < N_URBS; i++) {
+               usb_unlink_urb(dev->data_urbs_in[i]);
+               usb_unlink_urb(dev->data_urbs_out[i]);
+       }
+}
+
+static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
+{
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+       debug("snd_usb_caiaq_substream_open(%p)\n", substream);
+       substream->runtime->hw = dev->pcm_info;
+       snd_pcm_limit_hw_rates(substream->runtime);
+       return 0;
+}
+
+static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
+{
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+
+       debug("snd_usb_caiaq_substream_close(%p)\n", substream);
+       if (all_substreams_zero(dev->sub_playback) &&
+           all_substreams_zero(dev->sub_capture)) {
+               /* when the last client has stopped streaming, 
+                * all sample rates are allowed again */
+               stream_stop(dev);
+               dev->pcm_info.rates = dev->samplerates;
+       }
+       
+       return 0;
+}
+
+static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
+                                       struct snd_pcm_hw_params *hw_params)
+{
+       debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub);
+       return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
+}
+
+static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
+{
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+       debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub);
+       spin_lock_irq(&dev->spinlock);
+       deactivate_substream(dev, sub);
+       spin_unlock_irq(&dev->spinlock);
+       return snd_pcm_lib_free_pages(sub);
+}
+
+/* this should probably go upstream */
+#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
+#error "Change this table"
+#endif
+
+static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
+                                 48000, 64000, 88200, 96000, 176400, 192000 };
+
+static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       int bytes_per_sample, bpp, ret, i;
+       int index = substream->number;
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream);
+       
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1;
+       else
+               dev->audio_in_buf_pos[index] = 0;
+       
+       if (dev->streaming)
+               return 0;
+       
+       /* the first client that opens a stream defines the sample rate
+        * setting for all subsequent calls, until the last client closed. */
+       for (i=0; i < ARRAY_SIZE(rates); i++)
+               if (runtime->rate == rates[i])
+                       dev->pcm_info.rates = 1 << i;
+       
+       snd_pcm_limit_hw_rates(runtime);
+
+       bytes_per_sample = BYTES_PER_SAMPLE;
+       if (dev->spec.data_alignment == 2)
+               bytes_per_sample++;
+       
+       bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
+               * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;
+       
+       ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
+                                            runtime->sample_bits, bpp);
+       if (ret)
+               return ret;
+
+       ret = stream_start(dev);
+       if (ret)
+               return ret;
+       
+       dev->output_running = 0;
+       wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
+       if (!dev->output_running) {
+               stream_stop(dev);
+               return -EPIPE;
+       }
+
+       return 0;
+}
+
+static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
+{
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               spin_lock(&dev->spinlock);
+               activate_substream(dev, sub);
+               spin_unlock(&dev->spinlock);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               spin_lock(&dev->spinlock);
+               deactivate_substream(dev, sub);
+               spin_unlock(&dev->spinlock);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static snd_pcm_uframes_t
+snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
+{
+       int index = sub->number;
+       struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+
+       if (dev->input_panic || dev->output_panic)
+               return SNDRV_PCM_POS_XRUN;
+
+       if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               return bytes_to_frames(sub->runtime, 
+                                       dev->audio_out_buf_pos[index]);
+       else
+               return bytes_to_frames(sub->runtime,
+                                       dev->audio_in_buf_pos[index]);
+}
+
+/* operators for both playback and capture */
+static struct snd_pcm_ops snd_usb_caiaq_ops = {
+       .open =         snd_usb_caiaq_substream_open,
+       .close =        snd_usb_caiaq_substream_close,
+       .ioctl =        snd_pcm_lib_ioctl,
+       .hw_params =    snd_usb_caiaq_pcm_hw_params,
+       .hw_free =      snd_usb_caiaq_pcm_hw_free,
+       .prepare =      snd_usb_caiaq_pcm_prepare,
+       .trigger =      snd_usb_caiaq_pcm_trigger,
+       .pointer =      snd_usb_caiaq_pcm_pointer
+};
+       
+static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
+                                     struct snd_pcm_substream **subs)
+{
+       int stream, pb, *cnt;
+       struct snd_pcm_substream *sub;
+
+       for (stream = 0; stream < dev->n_streams; stream++) {
+               sub = subs[stream];
+               if (!sub)
+                       continue;
+
+               pb = frames_to_bytes(sub->runtime, 
+                                    sub->runtime->period_size);
+               cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+                                       &dev->period_out_count[stream] :
+                                       &dev->period_in_count[stream];
+
+               if (*cnt >= pb) {
+                       snd_pcm_period_elapsed(sub);
+                       *cnt %= pb;
+               }
+       }
+}
+
+static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
+                             const struct urb *urb,
+                             const struct usb_iso_packet_descriptor *iso)
+{
+       unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+       struct snd_pcm_substream *sub;
+       int stream, i;
+
+       if (all_substreams_zero(dev->sub_capture))
+               return;
+
+       spin_lock(&dev->spinlock);
+       
+       for (i = 0; i < iso->actual_length;) {
+               for (stream = 0; stream < dev->n_streams; stream++, i++) {
+                       sub = dev->sub_capture[stream];
+                       if (sub) {
+                               struct snd_pcm_runtime *rt = sub->runtime;
+                               char *audio_buf = rt->dma_area;
+                               int sz = frames_to_bytes(rt, rt->buffer_size);
+                               audio_buf[dev->audio_in_buf_pos[stream]++] 
+                                       = usb_buf[i];
+                               dev->period_in_count[stream]++;
+                               if (dev->audio_in_buf_pos[stream] == sz)
+                                       dev->audio_in_buf_pos[stream] = 0;
+                       }
+               }
+       }
+       
+       spin_unlock(&dev->spinlock);
+}
+
+static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
+                             const struct urb *urb,
+                             const struct usb_iso_packet_descriptor *iso)
+{
+       unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+       unsigned char check_byte;
+       struct snd_pcm_substream *sub;
+       int stream, i;
+
+       spin_lock(&dev->spinlock);
+       
+       for (i = 0; i < iso->actual_length;) {
+               if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
+                       for (stream = 0; 
+                            stream < dev->n_streams; 
+                            stream++, i++) {
+                               if (dev->first_packet)
+                                       continue;
+
+                               check_byte = MAKE_CHECKBYTE(dev, stream, i);
+                               
+                               if ((usb_buf[i] & 0x3f) != check_byte)
+                                       dev->input_panic = 1;
+
+                               if (usb_buf[i] & 0x80)
+                                       dev->output_panic = 1;
+                       }
+               }
+               dev->first_packet = 0;
+
+               for (stream = 0; stream < dev->n_streams; stream++, i++) {
+                       sub = dev->sub_capture[stream];
+                       if (sub) {
+                               struct snd_pcm_runtime *rt = sub->runtime;
+                               char *audio_buf = rt->dma_area;
+                               int sz = frames_to_bytes(rt, rt->buffer_size);
+                               audio_buf[dev->audio_in_buf_pos[stream]++] =
+                                       usb_buf[i];
+                               dev->period_in_count[stream]++;
+                               if (dev->audio_in_buf_pos[stream] == sz)
+                                       dev->audio_in_buf_pos[stream] = 0;
+                       }
+               }
+       }
+
+       spin_unlock(&dev->spinlock);
+}
+
+static void read_in_urb(struct snd_usb_caiaqdev *dev,
+                       const struct urb *urb,
+                       const struct usb_iso_packet_descriptor *iso)
+{
+       if (!dev->streaming)
+               return;
+
+       switch (dev->spec.data_alignment) {
+       case 0:
+               read_in_urb_mode0(dev, urb, iso);
+               break;
+       case 2:
+               read_in_urb_mode2(dev, urb, iso);
+               break;
+       }
+
+       if (dev->input_panic || dev->output_panic) {
+               debug("streaming error detected %s %s\n", 
+                               dev->input_panic ? "(input)" : "",
+                               dev->output_panic ? "(output)" : "");
+       }
+
+       check_for_elapsed_periods(dev, dev->sub_capture);
+}
+
+static void fill_out_urb(struct snd_usb_caiaqdev *dev, 
+                        struct urb *urb, 
+                        const struct usb_iso_packet_descriptor *iso)
+{
+       unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+       struct snd_pcm_substream *sub;
+       int stream, i;
+
+       spin_lock(&dev->spinlock);
+       
+       for (i = 0; i < iso->length;) {
+               for (stream = 0; stream < dev->n_streams; stream++, i++) {
+                       sub = dev->sub_playback[stream];
+                       if (sub) {
+                               struct snd_pcm_runtime *rt = sub->runtime;
+                               char *audio_buf = rt->dma_area;
+                               int sz = frames_to_bytes(rt, rt->buffer_size);
+                               usb_buf[i] =
+                                       audio_buf[dev->audio_out_buf_pos[stream]];
+                               dev->period_out_count[stream]++;
+                               dev->audio_out_buf_pos[stream]++;
+                               if (dev->audio_out_buf_pos[stream] == sz)
+                                       dev->audio_out_buf_pos[stream] = 0;
+                       } else
+                               usb_buf[i] = 0;
+               }
+
+               /* fill in the check bytes */
+               if (dev->spec.data_alignment == 2 &&
+                   i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 
+                       (dev->n_streams * CHANNELS_PER_STREAM))
+                   for (stream = 0; stream < dev->n_streams; stream++, i++)
+                       usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
+       }
+
+       spin_unlock(&dev->spinlock);
+       check_for_elapsed_periods(dev, dev->sub_playback);
+}
+
+static void read_completed(struct urb *urb)
+{
+       struct snd_usb_caiaq_cb_info *info = urb->context; 
+       struct snd_usb_caiaqdev *dev;
+       struct urb *out;
+       int frame, len, send_it = 0, outframe = 0;
+
+       if (urb->status || !info)
+               return;
+
+       dev = info->dev;
+       if (!dev->streaming)
+               return;
+
+       out = dev->data_urbs_out[info->index];
+
+       /* read the recently received packet and send back one which has
+        * the same layout */
+       for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+               if (urb->iso_frame_desc[frame].status)
+                       continue;
+
+               len = urb->iso_frame_desc[outframe].actual_length;
+               out->iso_frame_desc[outframe].length = len;
+               out->iso_frame_desc[outframe].actual_length = 0;
+               out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame;
+               
+               if (len > 0) {
+                       fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
+                       read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
+                       send_it = 1;
+               }
+
+               outframe++;
+       }
+
+       if (send_it) {
+               out->number_of_packets = FRAMES_PER_URB;
+               out->transfer_flags = URB_ISO_ASAP;
+               usb_submit_urb(out, GFP_ATOMIC);
+       }
+       
+       /* re-submit inbound urb */
+       for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+               urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
+               urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
+               urb->iso_frame_desc[frame].actual_length = 0;
+       }
+       
+       urb->number_of_packets = FRAMES_PER_URB;
+       urb->transfer_flags = URB_ISO_ASAP;
+       usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void write_completed(struct urb *urb)
+{
+       struct snd_usb_caiaq_cb_info *info = urb->context;
+       struct snd_usb_caiaqdev *dev = info->dev;
+
+       if (!dev->output_running) {
+               dev->output_running = 1;
+               wake_up(&dev->prepare_wait_queue);
+       }
+}
+
+static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
+{
+       int i, frame;
+       struct urb **urbs;
+       struct usb_device *usb_dev = dev->chip.dev;
+       unsigned int pipe;
+
+       pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? 
+               usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
+               usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
+
+       urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
+       if (!urbs) {
+               log("unable to kmalloc() urbs, OOM!?\n");
+               *ret = -ENOMEM;
+               return NULL;
+       }
+
+       for (i = 0; i < N_URBS; i++) {
+               urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
+               if (!urbs[i]) {
+                       log("unable to usb_alloc_urb(), OOM!?\n");
+                       *ret = -ENOMEM;
+                       return urbs;
+               }
+
+               urbs[i]->transfer_buffer = 
+                       kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
+               if (!urbs[i]->transfer_buffer) {
+                       log("unable to kmalloc() transfer buffer, OOM!?\n");
+                       *ret = -ENOMEM;
+                       return urbs;
+               }
+               
+               for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+                       struct usb_iso_packet_descriptor *iso = 
+                               &urbs[i]->iso_frame_desc[frame];
+                       
+                       iso->offset = BYTES_PER_FRAME * frame;
+                       iso->length = BYTES_PER_FRAME;
+               }
+               
+               urbs[i]->dev = usb_dev;
+               urbs[i]->pipe = pipe;
+               urbs[i]->transfer_buffer_length = FRAMES_PER_URB 
+                                               * BYTES_PER_FRAME;
+               urbs[i]->context = &dev->data_cb_info[i];
+               urbs[i]->interval = 1;
+               urbs[i]->transfer_flags = URB_ISO_ASAP;
+               urbs[i]->number_of_packets = FRAMES_PER_URB;
+               urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
+                                       read_completed : write_completed;
+       }
+
+       *ret = 0;
+       return urbs;
+}
+
+static void free_urbs(struct urb **urbs)
+{
+       int i;
+
+       if (!urbs)
+               return;
+
+       for (i = 0; i < N_URBS; i++) {
+               if (!urbs[i])
+                       continue;
+               
+               usb_kill_urb(urbs[i]);
+               kfree(urbs[i]->transfer_buffer);
+               usb_free_urb(urbs[i]);
+       }
+
+       kfree(urbs);
+}
+
+int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
+{
+       int i, ret;
+
+       dev->n_audio_in  = max(dev->spec.num_analog_audio_in, 
+                              dev->spec.num_digital_audio_in) / 
+                               CHANNELS_PER_STREAM;
+       dev->n_audio_out = max(dev->spec.num_analog_audio_out,
+                              dev->spec.num_digital_audio_out) / 
+                               CHANNELS_PER_STREAM;
+       dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);
+
+       debug("dev->n_audio_in = %d\n", dev->n_audio_in);
+       debug("dev->n_audio_out = %d\n", dev->n_audio_out);
+       debug("dev->n_streams = %d\n", dev->n_streams);
+
+       if (dev->n_streams > MAX_STREAMS) {
+               log("unable to initialize device, too many streams.\n");
+               return -EINVAL;
+       }
+
+       ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, 
+                       dev->n_audio_out, dev->n_audio_in, &dev->pcm);
+
+       if (ret < 0) {
+               log("snd_pcm_new() returned %d\n", ret);
+               return ret;
+       }
+
+       dev->pcm->private_data = dev;
+       strcpy(dev->pcm->name, dev->product_name);
+
+       memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
+       memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
+       
+       memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
+                       sizeof(snd_usb_caiaq_pcm_hardware));
+
+       /* setup samplerates */
+       dev->samplerates = dev->pcm_info.rates;
+       switch (dev->chip.usb_id) {
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+               dev->samplerates |= SNDRV_PCM_RATE_88200;
+               dev->samplerates |= SNDRV_PCM_RATE_192000;
+               break;
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
+               dev->samplerates |= SNDRV_PCM_RATE_88200;
+               break;
+       }
+
+       snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 
+                               &snd_usb_caiaq_ops);
+       snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 
+                               &snd_usb_caiaq_ops);
+
+       snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
+                                       SNDRV_DMA_TYPE_CONTINUOUS,
+                                       snd_dma_continuous_data(GFP_KERNEL),
+                                       MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
+
+       dev->data_cb_info =
+               kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, 
+                                       GFP_KERNEL);
+
+       if (!dev->data_cb_info)
+               return -ENOMEM;
+
+       for (i = 0; i < N_URBS; i++) {
+               dev->data_cb_info[i].dev = dev;
+               dev->data_cb_info[i].index = i;
+       }
+       
+       dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
+       if (ret < 0) {
+               kfree(dev->data_cb_info);
+               free_urbs(dev->data_urbs_in);
+               return ret;
+       }
+       
+       dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
+       if (ret < 0) {
+               kfree(dev->data_cb_info);
+               free_urbs(dev->data_urbs_in);
+               free_urbs(dev->data_urbs_out);
+               return ret;
+       }
+
+       return 0;
+}
+
+void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
+{
+       debug("snd_usb_caiaq_audio_free (%p)\n", dev);
+       stream_stop(dev);
+       free_urbs(dev->data_urbs_in);
+       free_urbs(dev->data_urbs_out);
+       kfree(dev->data_cb_info);
+}
+
diff --git a/sound/usb/caiaq/caiaq-audio.h b/sound/usb/caiaq/caiaq-audio.h
new file mode 100644 (file)
index 0000000..8ab1f8d
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef CAIAQ_AUDIO_H
+#define CAIAQ_AUDIO_H
+
+int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev);
+
+#endif /* CAIAQ_AUDIO_H */
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
new file mode 100644 (file)
index 0000000..4709347
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ * caiaq.c: ALSA driver for caiaq/NativeInstruments devices
+ *
+ *   Copyright (c) 2007 Daniel Mack <daniel@caiaq.de>
+ *                      Karsten Wiese <fzu@wemgehoertderstaat.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+
+#include "caiaq-device.h"
+#include "caiaq-audio.h"
+#include "caiaq-midi.h"
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+#include "caiaq-input.h"
+#endif
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
+                        "{Native Instruments, Kore Controller},"
+                        "{Native Instruments, Audio Kontrol 1}"
+                        "{Native Instruments, Audio 8 DJ}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
+static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static int snd_card_used[SNDRV_CARDS];
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
+
+enum {
+       SAMPLERATE_44100        = 0,
+       SAMPLERATE_48000        = 1,
+       SAMPLERATE_96000        = 2,
+       SAMPLERATE_192000       = 3,
+       SAMPLERATE_88200        = 4,
+       SAMPLERATE_INVALID      = 0xff
+};
+
+enum {
+       DEPTH_NONE      = 0,
+       DEPTH_16        = 1,
+       DEPTH_24        = 2,
+       DEPTH_32        = 3
+};
+
+static struct usb_device_id snd_usb_id_table[] = {
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     USB_VID_NATIVEINSTRUMENTS,
+               .idProduct =    USB_PID_RIGKONTROL2 
+       },
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     USB_VID_NATIVEINSTRUMENTS,
+               .idProduct =    USB_PID_KORECONTROLLER
+       },
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     USB_VID_NATIVEINSTRUMENTS,
+               .idProduct =    USB_PID_AK1
+       },
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     USB_VID_NATIVEINSTRUMENTS,
+               .idProduct =    USB_PID_AUDIO8DJ
+       },
+       { /* terminator */ }
+};
+
+static void usb_ep1_command_reply_dispatch (struct urb* urb)
+{
+       int ret;
+       struct snd_usb_caiaqdev *dev = urb->context;
+       unsigned char *buf = urb->transfer_buffer;
+
+       if (urb->status || !dev) {
+               log("received EP1 urb->status = %i\n", urb->status);
+               return;
+       }
+
+       switch(buf[0]) {
+       case EP1_CMD_GET_DEVICE_INFO:
+               memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec));
+               dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version);
+               debug("device spec (firmware %d): audio: %d in, %d out, "
+                       "MIDI: %d in, %d out, data alignment %d\n",
+                       dev->spec.fw_version,
+                       dev->spec.num_analog_audio_in,
+                       dev->spec.num_analog_audio_out,
+                       dev->spec.num_midi_in,
+                       dev->spec.num_midi_out,
+                       dev->spec.data_alignment);
+
+               dev->spec_received++;
+               wake_up(&dev->ep1_wait_queue);
+               break;
+       case EP1_CMD_AUDIO_PARAMS:
+               dev->audio_parm_answer = buf[1];
+               wake_up(&dev->ep1_wait_queue);
+               break;
+       case EP1_CMD_MIDI_READ:
+               snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
+               break;
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+       case EP1_CMD_READ_ERP:
+       case EP1_CMD_READ_ANALOG:
+       case EP1_CMD_READ_IO:
+               snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
+               break;
+#endif
+       }
+
+       dev->ep1_in_urb.actual_length = 0;
+       ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC);
+       if (ret < 0)
+               log("unable to submit urb. OOM!?\n");
+}
+
+static int send_command (struct snd_usb_caiaqdev *dev,
+                        unsigned char command, 
+                        const unsigned char *buffer,
+                        int len)
+{
+       int actual_len;
+       struct usb_device *usb_dev = dev->chip.dev;
+
+       if (!usb_dev)
+               return -EIO;
+
+       if (len > EP1_BUFSIZE - 1)
+               len = EP1_BUFSIZE - 1;
+
+       if (buffer && len > 0)
+               memcpy(dev->ep1_out_buf+1, buffer, len);
+       
+       dev->ep1_out_buf[0] = command;
+       return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
+                          dev->ep1_out_buf, len+1, &actual_len, 200);
+}
+
+int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
+                                   int rate, int depth, int bpp)
+{
+       int ret;
+       char tmp[5];
+       
+       switch (rate) {
+       case 44100:     tmp[0] = SAMPLERATE_44100;   break;
+       case 48000:     tmp[0] = SAMPLERATE_48000;   break;
+       case 88200:     tmp[0] = SAMPLERATE_88200;   break;
+       case 96000:     tmp[0] = SAMPLERATE_96000;   break;
+       case 192000:    tmp[0] = SAMPLERATE_192000;  break;
+       default:        return -EINVAL;
+       }
+
+       switch (depth) {
+       case 16:        tmp[1] = DEPTH_16;   break;
+       case 24:        tmp[1] = DEPTH_24;   break;
+       default:        return -EINVAL;
+       }
+
+       tmp[2] = bpp & 0xff;
+       tmp[3] = bpp >> 8;
+       tmp[4] = 1; /* packets per microframe */
+
+       debug("setting audio params: %d Hz, %d bits, %d bpp\n",
+               rate, depth, bpp);
+
+       dev->audio_parm_answer = -1;
+       ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp));
+
+       if (ret)
+               return ret;
+       
+       if (!wait_event_timeout(dev->ep1_wait_queue, 
+           dev->audio_parm_answer >= 0, HZ))
+               return -EPIPE;
+               
+       if (dev->audio_parm_answer != 1) 
+               debug("unable to set the device's audio params\n");
+
+       return dev->audio_parm_answer == 1 ? 0 : -EINVAL;
+}
+
+int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, 
+                               int digital, int analog, int erp)
+{
+       char tmp[3] = { digital, analog, erp };
+       return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp));
+}
+
+static void setup_card(struct snd_usb_caiaqdev *dev)
+{
+       int ret;
+       char val[3];
+       
+       /* device-specific startup specials */
+       switch (dev->chip.usb_id) {
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
+               /* RigKontrol2 - display centered dash ('-') */
+               val[0] = 0x00;
+               val[1] = 0x00;
+               val[2] = 0x01;
+               send_command(dev, EP1_CMD_WRITE_IO, val, 3);
+               break;
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+               /* Audio Kontrol 1 - make USB-LED stop blinking */
+               val[0] = 0x00;
+               send_command(dev, EP1_CMD_WRITE_IO, val, 1);
+               break;
+       }
+       
+       ret = snd_usb_caiaq_audio_init(dev);
+       if (ret < 0)
+               log("Unable to set up audio system (ret=%d)\n", ret);
+       
+       ret = snd_usb_caiaq_midi_init(dev);
+       if (ret < 0)
+               log("Unable to set up MIDI system (ret=%d)\n", ret);
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+       ret = snd_usb_caiaq_input_init(dev);
+       if (ret < 0)
+               log("Unable to set up input system (ret=%d)\n", ret);
+#endif
+
+       /* finally, register the card and all its sub-instances */
+       ret = snd_card_register(dev->chip.card);
+       if (ret < 0) {
+               log("snd_card_register() returned %d\n", ret);
+               snd_card_free(dev->chip.card);
+       }
+}
+
+static struct snd_card* create_card(struct usb_device* usb_dev)
+{
+       int devnum;
+       struct snd_card *card;
+       struct snd_usb_caiaqdev *dev;
+
+       for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
+               if (enable[devnum] && !snd_card_used[devnum])
+                       break;
+
+       if (devnum >= SNDRV_CARDS)
+               return NULL;
+
+       card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, 
+                                       sizeof(struct snd_usb_caiaqdev));
+       if (!card)
+               return NULL;
+
+       dev = caiaqdev(card);
+       dev->chip.dev = usb_dev;
+       dev->chip.card = card;
+       dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor,
+                                       usb_dev->descriptor.idProduct);
+       spin_lock_init(&dev->spinlock);
+       snd_card_set_dev(card, &usb_dev->dev);
+
+       return card;
+}
+
+static int init_card(struct snd_usb_caiaqdev *dev)
+{
+       char *c;
+       struct usb_device *usb_dev = dev->chip.dev;
+       struct snd_card *card = dev->chip.card;
+       int err, len;
+       
+       if (usb_set_interface(usb_dev, 0, 1) != 0) {
+               log("can't set alt interface.\n");
+               return -EIO;
+       }
+
+       usb_init_urb(&dev->ep1_in_urb);
+       usb_init_urb(&dev->midi_out_urb);
+
+       usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, 
+                         usb_rcvbulkpipe(usb_dev, 0x1),
+                         dev->ep1_in_buf, EP1_BUFSIZE, 
+                         usb_ep1_command_reply_dispatch, dev);
+
+       usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, 
+                         usb_sndbulkpipe(usb_dev, 0x1),
+                         dev->midi_out_buf, EP1_BUFSIZE, 
+                         snd_usb_caiaq_midi_output_done, dev);
+       
+       init_waitqueue_head(&dev->ep1_wait_queue);
+       init_waitqueue_head(&dev->prepare_wait_queue);
+       
+       if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
+               return -EIO;
+
+       err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
+       if (err)
+               return err;
+
+       if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
+               return -ENODEV;
+
+       usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
+                  dev->vendor_name, CAIAQ_USB_STR_LEN);
+       
+       usb_string(usb_dev, usb_dev->descriptor.iProduct,
+                  dev->product_name, CAIAQ_USB_STR_LEN);
+       
+       usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
+                  dev->serial, CAIAQ_USB_STR_LEN);
+
+       /* terminate serial string at first white space occurence */
+       c = strchr(dev->serial, ' ');
+       if (c)
+               *c = '\0';
+       
+       strcpy(card->driver, MODNAME);
+       strcpy(card->shortname, dev->product_name);
+
+       len = snprintf(card->longname, sizeof(card->longname),
+                      "%s %s (serial %s, ",
+                      dev->vendor_name, dev->product_name, dev->serial);
+
+       if (len < sizeof(card->longname) - 2)
+               len += usb_make_path(usb_dev, card->longname + len,
+                                    sizeof(card->longname) - len);
+
+       card->longname[len++] = ')';
+       card->longname[len] = '\0';
+       setup_card(dev);
+       return 0;
+}
+
+static int snd_probe(struct usb_interface *intf, 
+                    const struct usb_device_id *id)
+{
+       int ret;
+       struct snd_card *card;
+       struct usb_device *device = interface_to_usbdev(intf);
+       
+       card = create_card(device);
+       
+       if (!card)
+               return -ENOMEM;
+                       
+       dev_set_drvdata(&intf->dev, card);
+       ret = init_card(caiaqdev(card));
+       if (ret < 0) {
+               log("unable to init card! (ret=%d)\n", ret);
+               snd_card_free(card);
+               return ret;
+       }
+       
+       return 0;
+}
+
+static void snd_disconnect(struct usb_interface *intf)
+{
+       struct snd_usb_caiaqdev *dev;
+       struct snd_card *card = dev_get_drvdata(&intf->dev);
+
+       debug("snd_disconnect(%p)\n", intf);
+
+       if (!card)
+               return;
+
+       dev = caiaqdev(card);
+       snd_card_disconnect(card);
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+       snd_usb_caiaq_input_free(dev);
+#endif
+       snd_usb_caiaq_audio_free(dev);
+       
+       usb_kill_urb(&dev->ep1_in_urb);
+       usb_kill_urb(&dev->midi_out_urb);
+       
+       snd_card_free(card);
+       usb_reset_device(interface_to_usbdev(intf));
+}
+
+
+MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
+static struct usb_driver snd_usb_driver = {
+       .name           = MODNAME,
+       .probe          = snd_probe,
+       .disconnect     = snd_disconnect,
+       .id_table       = snd_usb_id_table,
+};
+
+static int __init snd_module_init(void)
+{
+       return usb_register(&snd_usb_driver);
+}
+
+static void __exit snd_module_exit(void)
+{
+       usb_deregister(&snd_usb_driver);
+}
+
+module_init(snd_module_init)
+module_exit(snd_module_exit)
+
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
new file mode 100644 (file)
index 0000000..088d5ec
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef CAIAQ_DEVICE_H
+#define CAIAQ_DEVICE_H
+
+#include "../usbaudio.h"
+
+#define USB_VID_NATIVEINSTRUMENTS 0x17cc
+
+#define USB_PID_RIGKONTROL2    0x1969
+#define USB_PID_KORECONTROLLER         0x4711
+#define USB_PID_AK1            0x0815
+#define USB_PID_AUDIO8DJ       0x1978
+
+#define EP1_BUFSIZE 64
+#define CAIAQ_USB_STR_LEN 0xff
+#define MAX_STREAMS 32
+
+//#define      SND_USB_CAIAQ_DEBUG
+
+#define MODNAME "snd-usb-caiaq"
+#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x)
+
+#ifdef SND_USB_CAIAQ_DEBUG
+#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x)
+#else
+#define debug(x...) do { } while(0)
+#endif
+
+#define EP1_CMD_GET_DEVICE_INFO        0x1
+#define EP1_CMD_READ_ERP       0x2
+#define EP1_CMD_READ_ANALOG    0x3
+#define EP1_CMD_READ_IO                0x4
+#define EP1_CMD_WRITE_IO       0x5
+#define EP1_CMD_MIDI_READ      0x6
+#define EP1_CMD_MIDI_WRITE     0x7
+#define EP1_CMD_AUDIO_PARAMS   0x9
+#define EP1_CMD_AUTO_MSG       0xb
+
+struct caiaq_device_spec {
+       unsigned short fw_version;
+       unsigned char hw_subtype;
+       unsigned char num_erp;
+       unsigned char num_analog_in;
+       unsigned char num_digital_in;
+       unsigned char num_digital_out;
+       unsigned char num_analog_audio_out;
+       unsigned char num_analog_audio_in;
+       unsigned char num_digital_audio_out;
+       unsigned char num_digital_audio_in;
+       unsigned char num_midi_out;
+       unsigned char num_midi_in;
+       unsigned char data_alignment;
+} __attribute__ ((packed));
+
+struct snd_usb_caiaq_cb_info;
+
+struct snd_usb_caiaqdev {
+       struct snd_usb_audio chip;
+
+       struct urb ep1_in_urb;
+       struct urb midi_out_urb;
+       struct urb **data_urbs_in;
+       struct urb **data_urbs_out;
+       struct snd_usb_caiaq_cb_info *data_cb_info;
+       
+       unsigned char ep1_in_buf[EP1_BUFSIZE];
+       unsigned char ep1_out_buf[EP1_BUFSIZE];
+       unsigned char midi_out_buf[EP1_BUFSIZE];
+
+       struct caiaq_device_spec spec;
+       spinlock_t spinlock;
+       wait_queue_head_t ep1_wait_queue;
+       wait_queue_head_t prepare_wait_queue;
+       int spec_received, audio_parm_answer;
+       
+       char vendor_name[CAIAQ_USB_STR_LEN];
+       char product_name[CAIAQ_USB_STR_LEN];
+       char serial[CAIAQ_USB_STR_LEN];
+
+       int n_streams, n_audio_in, n_audio_out;
+       int streaming, first_packet, output_running;
+       int audio_in_buf_pos[MAX_STREAMS];
+       int audio_out_buf_pos[MAX_STREAMS];
+       int period_in_count[MAX_STREAMS];
+       int period_out_count[MAX_STREAMS];
+       int input_panic, output_panic;
+       char *audio_in_buf, *audio_out_buf;
+       unsigned int samplerates;
+
+       struct snd_pcm_substream *sub_playback[MAX_STREAMS];
+       struct snd_pcm_substream *sub_capture[MAX_STREAMS];
+
+       /* Linux input */
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+       struct input_dev *input_dev;
+#endif
+       
+       /* ALSA */
+       struct snd_pcm *pcm;
+       struct snd_pcm_hardware pcm_info;
+       struct snd_rawmidi *rmidi;
+       struct snd_rawmidi_substream *midi_receive_substream;
+       struct snd_rawmidi_substream *midi_out_substream;
+};
+
+struct snd_usb_caiaq_cb_info {
+       struct snd_usb_caiaqdev *dev;
+       int index;
+};
+
+#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data)
+
+int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
+int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
+
+
+#endif /* CAIAQ_DEVICE_H */
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
new file mode 100644 (file)
index 0000000..3acd12d
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *   Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+#include <sound/pcm.h>
+#include "caiaq-device.h"
+#include "caiaq-input.h"
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+
+static unsigned char keycode_ak1[] =  { KEY_C, KEY_B, KEY_A };
+static unsigned char keycode_rk2[] =  { KEY_1, KEY_2, KEY_3, KEY_4, 
+                                       KEY_5, KEY_6, KEY_7 };
+
+#define DEG90  (range/2)
+#define DEG180 (range)
+#define DEG270 (DEG90 + DEG180)
+#define DEG360 (DEG180 * 2)
+#define HIGH_PEAK (268)
+#define LOW_PEAK (-7)
+
+/* some of these devices have endless rotation potentiometers
+ * built in which use two tapers, 90 degrees phase shifted.
+ * this algorithm decodes them to one single value, ranging
+ * from 0 to 999 */
+static unsigned int decode_erp(unsigned char a, unsigned char b)
+{
+       int weight_a, weight_b;
+       int pos_a, pos_b;
+       int ret;
+       int range = HIGH_PEAK - LOW_PEAK;
+       int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
+
+       weight_b = abs(mid_value-a) - (range/2 - 100)/2;
+       
+       if (weight_b < 0)
+               weight_b = 0;
+
+       if (weight_b > 100)
+               weight_b = 100;
+
+       weight_a = 100 - weight_b;
+
+       if (a < mid_value) {
+               /* 0..90 and 270..360 degrees */
+               pos_b = b - LOW_PEAK + DEG270;
+               if (pos_b >= DEG360)
+                       pos_b -= DEG360;
+       } else
+               /* 90..270 degrees */
+               pos_b = HIGH_PEAK - b + DEG90;
+
+
+       if (b > mid_value)
+               /* 0..180 degrees */
+               pos_a = a - LOW_PEAK;
+       else
+               /* 180..360 degrees */
+               pos_a = HIGH_PEAK - a + DEG180;
+
+       /* interpolate both slider values, depending on weight factors */
+       /* 0..99 x DEG360 */
+       ret = pos_a * weight_a + pos_b * weight_b;
+
+       /* normalize to 0..999 */
+       ret *= 10;
+       ret /= DEG360;
+
+       if (ret < 0)
+               ret += 1000;
+       
+       if (ret >= 1000)
+               ret -= 1000;
+
+       return ret;
+}
+
+#undef DEG90
+#undef DEG180
+#undef DEG270
+#undef DEG360
+#undef HIGH_PEAK
+#undef LOW_PEAK
+
+
+static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, 
+                                       const char *buf, unsigned int len)
+{
+       switch(dev->input_dev->id.product) {
+       case USB_PID_RIGKONTROL2:
+               input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]);
+               input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]);
+               input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]);
+               input_sync(dev->input_dev);
+               break;
+       }
+}
+
+static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, 
+                                    const char *buf, unsigned int len)
+{
+       int i;
+
+       switch(dev->input_dev->id.product) {
+       case USB_PID_AK1:
+               i = decode_erp(buf[0], buf[1]);
+               input_report_abs(dev->input_dev, ABS_X, i);
+               input_sync(dev->input_dev);     
+               break;
+       }
+}
+
+static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, 
+                                   char *buf, unsigned int len)
+{
+       int i;
+       unsigned char *keycode = dev->input_dev->keycode;
+
+       if (!keycode)
+               return;
+
+       if (dev->input_dev->id.product == USB_PID_RIGKONTROL2)
+               for (i=0; i<len; i++)
+                       buf[i] = ~buf[i];
+
+       for (i=0; (i<dev->input_dev->keycodemax) && (i < len); i++)
+               input_report_key(dev->input_dev, keycode[i], 
+                                       buf[i/8] & (1 << (i%8)));
+
+       input_sync(dev->input_dev);
+}
+
+void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, 
+                                 char *buf, 
+                                 unsigned int len)
+{
+       if (!dev->input_dev || (len < 1))
+               return;
+
+       switch (buf[0]) {
+       case EP1_CMD_READ_ANALOG:
+               snd_caiaq_input_read_analog(dev, buf+1, len-1);
+               break;
+       case EP1_CMD_READ_ERP:
+               snd_caiaq_input_read_erp(dev, buf+1, len-1);
+               break;
+       case EP1_CMD_READ_IO:
+               snd_caiaq_input_read_io(dev, buf+1, len-1);
+               break;
+       }
+}
+
+int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
+{
+       struct usb_device *usb_dev = dev->chip.dev;
+       struct input_dev *input;
+       int i, ret;
+
+       input = input_allocate_device();
+       if (!input)
+               return -ENOMEM;
+
+       input->name = dev->product_name;
+       input->id.bustype = BUS_USB;
+       input->id.vendor  = usb_dev->descriptor.idVendor;
+       input->id.product = usb_dev->descriptor.idProduct;
+       input->id.version = usb_dev->descriptor.bcdDevice;
+
+        switch (dev->chip.usb_id) {
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
+               input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+               input->keycode = keycode_rk2;
+               input->keycodesize = sizeof(char);
+               input->keycodemax = ARRAY_SIZE(keycode_rk2);
+               for (i=0; i<ARRAY_SIZE(keycode_rk2); i++)
+                       set_bit(keycode_rk2[i], input->keybit);
+
+               input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
+               input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
+               input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
+               snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
+               break;
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+               input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input->absbit[0] = BIT(ABS_X);
+               input->keycode = keycode_ak1;
+               input->keycodesize = sizeof(char);
+               input->keycodemax = ARRAY_SIZE(keycode_ak1);
+               for (i=0; i<ARRAY_SIZE(keycode_ak1); i++)
+                       set_bit(keycode_ak1[i], input->keybit);
+
+               input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
+               snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
+               break;
+       default:
+               /* no input methods supported on this device */
+               input_free_device(input);
+               return 0;
+       }
+
+       ret = input_register_device(input);
+       if (ret < 0) {
+               input_free_device(input);
+               return ret;
+       }
+
+       dev->input_dev = input;
+       return 0;
+}
+
+void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
+{
+       if (!dev || !dev->input_dev)
+               return;
+
+       input_unregister_device(dev->input_dev);
+       input_free_device(dev->input_dev);
+       dev->input_dev = NULL;
+}
+
+#endif /* CONFIG_SND_USB_CAIAQ_INPUT */
+
diff --git a/sound/usb/caiaq/caiaq-input.h b/sound/usb/caiaq/caiaq-input.h
new file mode 100644 (file)
index 0000000..ced5355
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CAIAQ_INPUT_H
+#define CAIAQ_INPUT_H
+
+void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len);
+int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev);
+
+#endif
diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c
new file mode 100644 (file)
index 0000000..793ca20
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *   Copyright (c) 2006,2007 Daniel Mack
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+#include <sound/pcm.h>
+
+#include "caiaq-device.h"
+#include "caiaq-midi.h"
+
+
+static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
+{
+       struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
+
+       if (!dev)
+               return;
+       
+       dev->midi_receive_substream = up ? substream : NULL;
+}
+
+
+static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+       return 0;
+}
+
+static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
+                                   struct snd_rawmidi_substream *substream)
+{
+       int len, ret;
+       
+       dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
+       dev->midi_out_buf[1] = 0; /* port */
+       len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3);
+       
+       if (len <= 0)
+               return;
+       
+       dev->midi_out_buf[2] = len;
+       dev->midi_out_urb.transfer_buffer_length = len+3;
+       
+       ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
+       if (ret < 0)
+               log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n",
+                               substream, ret);
+}
+
+static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
+{
+       struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
+       
+       if (dev->midi_out_substream != NULL)
+               return;
+       
+       if (!up) {
+               dev->midi_out_substream = NULL;
+               return;
+       }
+       
+       dev->midi_out_substream = substream;
+       snd_usb_caiaq_midi_send(dev, substream);
+}
+
+
+static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
+{
+       .open =         snd_usb_caiaq_midi_output_open,
+       .close =        snd_usb_caiaq_midi_output_close,
+       .trigger =      snd_usb_caiaq_midi_output_trigger,
+};
+
+static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
+{
+       .open =         snd_usb_caiaq_midi_input_open,
+       .close =        snd_usb_caiaq_midi_input_close,
+       .trigger =      snd_usb_caiaq_midi_input_trigger,
+};
+
+void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, 
+                                    int port, const char *buf, int len)
+{
+       if (!dev->midi_receive_substream)
+               return;
+       
+       snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
+}
+
+int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
+{
+       int ret;
+       struct snd_rawmidi *rmidi;
+
+       ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
+                                       device->spec.num_midi_out,
+                                       device->spec.num_midi_in,
+                                       &rmidi);
+
+       if (ret < 0)
+               return ret;
+
+       strcpy(rmidi->name, device->product_name);
+
+       rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
+       rmidi->private_data = device;
+
+       if (device->spec.num_midi_out > 0) {
+               rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
+               snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 
+                                   &snd_usb_caiaq_midi_output);
+       }
+
+       if (device->spec.num_midi_in > 0) {
+               rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
+               snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 
+                                   &snd_usb_caiaq_midi_input);
+       }
+       
+       device->rmidi = rmidi;
+
+       return 0;
+}
+
+void snd_usb_caiaq_midi_output_done(struct urb* urb)
+{
+       struct snd_usb_caiaqdev *dev = urb->context;
+       char *buf = urb->transfer_buffer;
+       
+       if (urb->status != 0)
+               return;
+
+       if (!dev->midi_out_substream)
+               return;
+
+       snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);
+       dev->midi_out_substream = NULL;
+       snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
+}
+
diff --git a/sound/usb/caiaq/caiaq-midi.h b/sound/usb/caiaq/caiaq-midi.h
new file mode 100644 (file)
index 0000000..9d16db0
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CAIAQ_MIDI_H
+#define CAIAQ_MIDI_H
+
+int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
+void snd_usb_caiaq_midi_output_done(struct urb* urb);
+
+#endif /* CAIAQ_MIDI_H */
index b6d886373bb001b46da476a0cb1a2f3c6d44db19..8ebc1adb5ed9818ddb9c6d8cfef453ca418110cd 100644 (file)
@@ -1878,6 +1878,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
        }
 
        /* set the period time minimum 1ms */
+       /* FIXME: high-speed mode allows 125us minimum period, but many parts
+        * in the current code assume the 1ms period.
+        */
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
                                     1000 * MIN_PACKS_URB,
                                     /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
index 24f5a26c5f0c7fede90c066e01320a1e3674f4bf..99295f9b76910eb9610243170dab6acdfcd2e971 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * usbmidi.c - ALSA USB MIDI driver
  *
- * Copyright (c) 2002-2005 Clemens Ladisch
+ * Copyright (c) 2002-2007 Clemens Ladisch
  * All rights reserved.
  *
  * Based on the OSS usb-midi driver by NAGANO Daisuke,
@@ -145,6 +145,7 @@ struct snd_usb_midi_in_endpoint {
        struct urb* urb;
        struct usbmidi_in_port {
                struct snd_rawmidi_substream *substream;
+               u8 running_status_length;
        } ports[0x10];
        u8 seen_f5;
        u8 error_resubmit;
@@ -365,6 +366,46 @@ static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep,
                }
 }
 
+/*
+ * Buggy M-Audio device: running status on input results in a packet that has
+ * the data bytes but not the status byte and that is marked with CIN 4.
+ */
+static void snd_usbmidi_maudio_broken_running_status_input(
+                                       struct snd_usb_midi_in_endpoint* ep,
+                                       uint8_t* buffer, int buffer_length)
+{
+       int i;
+
+       for (i = 0; i + 3 < buffer_length; i += 4)
+               if (buffer[i] != 0) {
+                       int cable = buffer[i] >> 4;
+                       u8 cin = buffer[i] & 0x0f;
+                       struct usbmidi_in_port *port = &ep->ports[cable];
+                       int length;
+                       
+                       length = snd_usbmidi_cin_length[cin];
+                       if (cin == 0xf && buffer[i + 1] >= 0xf8)
+                               ; /* realtime msg: no running status change */
+                       else if (cin >= 0x8 && cin <= 0xe)
+                               /* channel msg */
+                               port->running_status_length = length - 1;
+                       else if (cin == 0x4 &&
+                                port->running_status_length != 0 &&
+                                buffer[i + 1] < 0x80)
+                               /* CIN 4 that is not a SysEx */
+                               length = port->running_status_length;
+                       else
+                               /*
+                                * All other msgs cannot begin running status.
+                                * (A channel msg sent as two or three CIN 0xF
+                                * packets could in theory, but this device
+                                * doesn't use this format.)
+                                */
+                               port->running_status_length = 0;
+                       snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
+               }
+}
+
 /*
  * Adds one USB MIDI packet to the output buffer.
  */
@@ -525,6 +566,12 @@ static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
        .output_packet = snd_usbmidi_output_midiman_packet,
 };
 
+static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
+       .input = snd_usbmidi_maudio_broken_running_status_input,
+       .output = snd_usbmidi_standard_output, 
+       .output_packet = snd_usbmidi_output_standard_packet,
+};
+
 /*
  * Novation USB MIDI protocol: number of data bytes is in the first byte
  * (when receiving) (+1!) or in the second byte (when sending); data begins
@@ -918,7 +965,11 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
        }
        /* we never use interrupt output pipes */
        pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
-       ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
+       if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
+               /* FIXME: we need more URBs to get reasonable bandwidth here: */
+               ep->max_transfer = 4;
+       else
+               ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
        buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer,
                                  GFP_KERNEL, &ep->urb->transfer_dma);
        if (!buffer) {
@@ -1606,6 +1657,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
        switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
        case QUIRK_MIDI_STANDARD_INTERFACE:
                err = snd_usbmidi_get_ms_info(umidi, endpoints);
+               if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
+                       umidi->usb_protocol_ops =
+                               &snd_usbmidi_maudio_broken_running_status_ops;
                break;
        case QUIRK_MIDI_FIXED_ENDPOINT:
                memcpy(&endpoints[0], quirk->data,
index 858262068f4fe5ff4502e0d1df9221ef029f6532..8fcbe93b258927c5ffb45440cc4663ff10548163 100644 (file)
        .idProduct = prod, \
        .bInterfaceClass = USB_CLASS_VENDOR_SPEC
 
+/*
+ * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
+ * class matches do not take effect without an explicit ID match.
+ */
+{
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x046d,
+       .idProduct = 0x08f0,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
+{
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x046d,
+       .idProduct = 0x08f6,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
+
 /*
  * Yamaha devices
  */