From e2f132022888fb75d84966a39aeac0256854c672 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 5 Feb 2007 16:28:25 -0800 Subject: [PATCH] --- yaml --- r: 47278 b: refs/heads/master c: b454cc6636d254fbf6049b73e9560aee76fb04a3 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/crypto/api-intro.txt | 4 - .../feature-removal-schedule.txt | 12 + .../sound/alsa/ALSA-Configuration.txt | 60 +- .../sound/alsa/DocBook/alsa-driver-api.tmpl | 4 +- .../alsa/DocBook/writing-an-alsa-driver.tmpl | 33 +- trunk/Documentation/sound/alsa/hda_codec.txt | 10 +- trunk/Documentation/sound/alsa/soc/DAI.txt | 56 - .../Documentation/sound/alsa/soc/clocking.txt | 51 - trunk/Documentation/sound/alsa/soc/codec.txt | 197 -- trunk/Documentation/sound/alsa/soc/dapm.txt | 297 -- .../Documentation/sound/alsa/soc/machine.txt | 113 - .../Documentation/sound/alsa/soc/overview.txt | 83 - .../Documentation/sound/alsa/soc/platform.txt | 58 - .../sound/alsa/soc/pops_clicks.txt | 52 - trunk/MAINTAINERS | 15 +- trunk/arch/avr32/boards/atstk1000/Makefile | 2 +- trunk/arch/avr32/boards/atstk1000/atstk1002.c | 53 +- trunk/arch/avr32/boards/atstk1000/spi.c | 27 + trunk/arch/avr32/kernel/cpu.c | 1 - trunk/arch/avr32/kernel/irq.c | 1 - trunk/arch/avr32/kernel/setup.c | 4 +- trunk/arch/avr32/lib/libgcc.h | 33 + trunk/arch/avr32/lib/longlong.h | 98 + trunk/arch/avr32/mach-at32ap/Makefile | 2 +- trunk/arch/avr32/mach-at32ap/at32ap7000.c | 60 +- trunk/arch/avr32/mach-at32ap/extint.c | 36 +- trunk/arch/avr32/mach-at32ap/pio.c | 255 +- trunk/arch/avr32/mm/cache.c | 32 +- trunk/arch/i386/kernel/hpet.c | 5 +- trunk/arch/i386/kernel/io_apic.c | 2 +- trunk/arch/i386/mm/pageattr.c | 2 +- trunk/arch/ia64/kernel/crash.c | 2 +- trunk/arch/ia64/kernel/smp.c | 4 +- trunk/arch/powerpc/platforms/cell/iommu.c | 5 +- trunk/arch/powerpc/platforms/celleb/pci.c | 12 +- .../arch/powerpc/platforms/celleb/scc_epci.c | 56 +- trunk/arch/powerpc/platforms/chrp/setup.c | 4 +- trunk/arch/powerpc/platforms/ps3/interrupt.c | 2 - trunk/arch/powerpc/platforms/ps3/system-bus.c | 2 - trunk/arch/powerpc/xmon/spu-dis.c | 2 +- trunk/arch/s390/defconfig | 3 +- trunk/crypto/Kconfig | 31 - trunk/crypto/Makefile | 3 - trunk/crypto/algapi.c | 15 +- trunk/crypto/api.c | 80 +- trunk/crypto/blkcipher.c | 9 +- trunk/crypto/camellia.c | 1801 ----------- trunk/crypto/cbc.c | 9 +- trunk/crypto/cipher.c | 447 ++- trunk/crypto/compress.c | 5 + trunk/crypto/digest.c | 24 +- trunk/crypto/ecb.c | 9 +- trunk/crypto/fcrypt.c | 423 --- trunk/crypto/hash.c | 5 +- trunk/crypto/hmac.c | 9 +- trunk/crypto/internal.h | 27 +- trunk/crypto/lrw.c | 11 +- trunk/crypto/pcbc.c | 349 --- trunk/crypto/tcrypt.c | 73 +- trunk/crypto/tcrypt.h | 538 +--- trunk/crypto/xcbc.c | 60 +- trunk/drivers/acpi/bay.c | 2 +- trunk/drivers/ata/ahci.c | 2 +- trunk/drivers/ata/sata_svw.c | 6 +- trunk/drivers/char/watchdog/machzwd.c | 2 +- trunk/drivers/crypto/geode-aes.c | 2 +- trunk/drivers/hwmon/ams/ams-input.c | 2 +- .../infiniband/ulp/iser/iser_initiator.c | 4 +- trunk/drivers/input/touchscreen/ucb1400_ts.c | 2 +- trunk/drivers/kvm/kvm_main.c | 63 +- trunk/drivers/kvm/mmu.c | 2 +- trunk/drivers/kvm/svm.c | 8 +- trunk/drivers/kvm/vmx.c | 2 +- trunk/drivers/macintosh/rack-meter.c | 6 +- trunk/drivers/media/common/ir-keymaps.c | 1 + .../media/video/usbvision/usbvision-video.c | 2 +- trunk/drivers/misc/Kconfig | 2 +- trunk/drivers/misc/lkdtm.c | 4 +- trunk/drivers/mmc/Kconfig | 2 +- trunk/drivers/net/3c503.c | 3 +- trunk/drivers/net/Kconfig | 11 - trunk/drivers/net/Makefile | 1 - trunk/drivers/net/ac3200.c | 3 +- trunk/drivers/net/atl1/Makefile | 2 - trunk/drivers/net/atl1/atl1.h | 283 -- trunk/drivers/net/atl1/atl1_ethtool.c | 508 --- trunk/drivers/net/atl1/atl1_hw.c | 718 ----- trunk/drivers/net/atl1/atl1_hw.h | 951 ------ trunk/drivers/net/atl1/atl1_main.c | 2468 --------------- trunk/drivers/net/atl1/atl1_param.c | 206 -- trunk/drivers/net/bonding/bond_alb.c | 4 +- trunk/drivers/net/bonding/bond_main.c | 4 +- trunk/drivers/net/cxgb3/cxgb3_main.c | 86 +- trunk/drivers/net/cxgb3/cxgb3_offload.c | 4 +- trunk/drivers/net/e2100.c | 3 +- trunk/drivers/net/es3210.c | 2 +- trunk/drivers/net/macsonic.c | 1 - trunk/drivers/net/mv643xx_eth.c | 1 + trunk/drivers/net/r8169.c | 4 +- trunk/drivers/net/s2io.c | 2 +- trunk/drivers/net/s2io.h | 6 +- trunk/drivers/net/slip.c | 5 +- trunk/drivers/net/smc-mca.c | 3 +- trunk/drivers/net/smc-ultra.c | 3 +- trunk/drivers/net/smc-ultra32.c | 3 +- trunk/drivers/net/spider_net.c | 2 +- trunk/drivers/net/tg3.c | 2 +- trunk/drivers/net/ucc_geth.c | 79 +- trunk/drivers/net/ucc_geth_phy.c | 2 - trunk/drivers/net/wan/pc300too.c | 16 +- trunk/drivers/net/wd.c | 2 +- trunk/drivers/pcmcia/m32r_pcc.c | 2 +- trunk/drivers/rtc/rtc-dev.c | 2 +- trunk/drivers/s390/char/monreader.c | 218 +- trunk/drivers/s390/char/vmlogrdr.c | 279 +- trunk/drivers/s390/net/Kconfig | 7 + trunk/drivers/s390/net/Makefile | 1 + trunk/drivers/s390/net/iucv.c | 2540 +++++++++++++++ trunk/drivers/s390/net/iucv.h | 849 +++++ trunk/drivers/s390/net/netiucv.c | 1314 ++++---- trunk/drivers/s390/net/smsgiucv.c | 147 +- trunk/drivers/scsi/iscsi_tcp.c | 2 +- trunk/drivers/scsi/libiscsi.c | 40 +- trunk/drivers/scsi/osst.c | 8 +- trunk/drivers/scsi/osst.h | 68 +- trunk/drivers/serial/uartlite.c | 6 +- trunk/drivers/tc/Makefile | 2 +- trunk/drivers/tc/tc-driver.c | 110 + trunk/drivers/tc/tc.c | 339 +- trunk/drivers/usb/host/ehci-ps3.c | 2 +- trunk/drivers/usb/host/ehci.h | 12 +- trunk/drivers/usb/host/ohci-ps3.c | 2 +- trunk/drivers/usb/host/ohci.h | 12 +- trunk/drivers/usb/net/gl620a.c | 26 +- trunk/drivers/usb/serial/cp2101.c | 8 +- trunk/fs/dlm/lowcomms-tcp.c | 23 +- trunk/fs/ecryptfs/crypto.c | 4 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 1 + trunk/include/asm-alpha/io.h | 9 + trunk/include/asm-arm/arch-ixp4xx/io.h | 3 + trunk/include/asm-arm/io.h | 5 + .../asm-avr32/arch-at32ap/at32ap7000.h | 2 - trunk/include/asm-avr32/arch-at32ap/gpio.h | 27 - trunk/include/asm-avr32/arch-at32ap/irq.h | 14 - trunk/include/asm-avr32/arch-at32ap/portmux.h | 8 +- trunk/include/asm-avr32/checksum.h | 2 +- trunk/include/asm-avr32/dma-mapping.h | 8 - trunk/include/asm-avr32/gpio.h | 6 - trunk/include/asm-avr32/irq.h | 8 +- trunk/include/asm-avr32/posix_types.h | 2 +- trunk/include/asm-avr32/uaccess.h | 6 + trunk/include/asm-cris/io.h | 5 + trunk/include/asm-i386/io.h | 6 + trunk/include/asm-mips/dec/tc.h | 41 - trunk/include/asm-mips/dec/tcinfo.h | 47 - trunk/include/asm-mips/dec/tcmodule.h | 39 - trunk/include/asm-mips/io.h | 6 + trunk/include/asm-parisc/io.h | 9 + trunk/include/asm-ppc/io.h | 2 + trunk/include/asm-x86_64/io.h | 6 + trunk/include/crypto/algapi.h | 24 +- trunk/include/linux/atmarp.h | 2 + trunk/include/linux/crypto.h | 148 +- trunk/include/linux/gfp.h | 2 +- trunk/include/linux/i2c-id.h | 2 - trunk/include/linux/if_packet.h | 10 - trunk/include/linux/net.h | 2 +- trunk/include/linux/netdevice.h | 2 +- trunk/include/linux/netfilter/Kbuild | 1 - .../linux/netfilter/nf_conntrack_sane.h | 21 - .../linux/netfilter/nf_conntrack_tcp.h | 4 +- trunk/include/linux/netfilter/xt_TCPMSS.h | 10 - trunk/include/linux/netfilter_ipv4/ip_nat.h | 1 - .../include/linux/netfilter_ipv4/ip_tables.h | 22 +- .../include/linux/netfilter_ipv4/ipt_TCPMSS.h | 7 +- .../include/linux/netfilter_ipv6/ip6_tables.h | 35 +- trunk/include/linux/netfilter_ipv6/ip6t_mh.h | 15 - trunk/include/linux/pagemap.h | 2 + trunk/include/linux/pci_ids.h | 2 - trunk/include/linux/pfkeyv2.h | 4 +- trunk/include/linux/socket.h | 4 +- trunk/include/linux/sysctl.h | 3 +- trunk/include/linux/tc.h | 141 + trunk/include/linux/tcp.h | 2 +- trunk/include/linux/wanrouter.h | 8 + trunk/include/linux/xfrm.h | 19 - trunk/include/net/inet_hashtables.h | 10 +- trunk/include/net/iucv/af_iucv.h | 106 - trunk/include/net/iucv/iucv.h | 415 --- trunk/include/net/netfilter/nf_conntrack.h | 2 - trunk/include/net/netfilter/nf_nat.h | 1 - trunk/include/net/route.h | 5 +- trunk/include/net/tcp.h | 5 +- trunk/include/net/x25.h | 18 - trunk/include/net/xfrm.h | 47 - trunk/include/scsi/iscsi_proto.h | 46 +- trunk/include/sound/ac97_codec.h | 4 +- trunk/include/sound/ad1848.h | 2 +- trunk/include/sound/ak4114.h | 3 +- trunk/include/sound/ak4117.h | 2 +- trunk/include/sound/ak4xxx-adda.h | 6 +- trunk/include/sound/control.h | 5 +- trunk/include/sound/core.h | 62 +- trunk/include/sound/emu10k1.h | 418 +-- trunk/include/sound/pcm.h | 4 - trunk/include/sound/pt2258.h | 37 - trunk/include/sound/sb16_csp.h | 14 - trunk/include/sound/snd_wavefront.h | 2 - trunk/include/sound/soc-dapm.h | 286 -- trunk/include/sound/soc.h | 461 --- trunk/include/sound/typedefs.h | 173 ++ trunk/include/sound/version.h | 4 +- trunk/include/sound/vx_core.h | 2 +- trunk/include/sound/ymfpci.h | 6 +- trunk/mm/filemap.c | 20 + trunk/net/Kconfig | 1 - trunk/net/Makefile | 1 - trunk/net/atm/common.c | 3 +- trunk/net/bluetooth/hidp/hidp.h | 2 +- trunk/net/bluetooth/hidp/sock.c | 2 +- trunk/net/bridge/br_netfilter.c | 29 +- trunk/net/bridge/br_netlink.c | 14 +- trunk/net/bridge/netfilter/ebt_ip.c | 1 - trunk/net/bridge/netfilter/ebt_log.c | 1 - trunk/net/core/dev.c | 13 +- trunk/net/core/dst.c | 9 +- trunk/net/core/fib_rules.c | 14 +- trunk/net/core/neighbour.c | 29 +- trunk/net/core/rtnetlink.c | 23 +- trunk/net/dccp/ccids/ccid3.c | 5 +- trunk/net/dccp/ipv4.c | 2 +- trunk/net/dccp/ipv6.c | 2 +- trunk/net/dccp/proto.c | 4 +- trunk/net/decnet/dn_dev.c | 14 +- trunk/net/decnet/dn_table.c | 11 +- trunk/net/ipv4/af_inet.c | 2 +- trunk/net/ipv4/datagram.c | 2 +- trunk/net/ipv4/devinet.c | 14 +- trunk/net/ipv4/fib_semantics.c | 14 +- trunk/net/ipv4/igmp.c | 2 - trunk/net/ipv4/inet_diag.c | 19 +- trunk/net/ipv4/inet_hashtables.c | 2 +- trunk/net/ipv4/inet_timewait_sock.c | 4 +- trunk/net/ipv4/ip_gre.c | 3 +- trunk/net/ipv4/ipip.c | 3 +- trunk/net/ipv4/netfilter/Kconfig | 26 + trunk/net/ipv4/netfilter/Makefile | 1 + .../ipv4/netfilter/ip_conntrack_proto_tcp.c | 40 +- trunk/net/ipv4/netfilter/ip_nat_core.c | 12 +- trunk/net/ipv4/netfilter/ip_nat_helper.c | 2 +- trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c | 5 - trunk/net/ipv4/netfilter/ip_nat_proto_udp.c | 5 - trunk/net/ipv4/netfilter/ip_nat_rule.c | 32 +- trunk/net/ipv4/netfilter/ip_tables.c | 40 +- trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c | 15 +- trunk/net/ipv4/netfilter/ipt_ECN.c | 13 +- trunk/net/ipv4/netfilter/ipt_LOG.c | 16 +- trunk/net/ipv4/netfilter/ipt_MASQUERADE.c | 9 +- trunk/net/ipv4/netfilter/ipt_NETMAP.c | 8 +- trunk/net/ipv4/netfilter/ipt_REDIRECT.c | 8 +- trunk/net/ipv4/netfilter/ipt_REJECT.c | 12 +- trunk/net/ipv4/netfilter/ipt_SAME.c | 8 +- trunk/net/ipv4/netfilter/ipt_TCPMSS.c | 207 ++ trunk/net/ipv4/netfilter/ipt_TOS.c | 11 +- trunk/net/ipv4/netfilter/ipt_TTL.c | 11 +- trunk/net/ipv4/netfilter/ipt_ULOG.c | 18 +- trunk/net/ipv4/netfilter/ipt_addrtype.c | 9 +- trunk/net/ipv4/netfilter/ipt_ah.c | 10 +- trunk/net/ipv4/netfilter/ipt_ecn.c | 10 +- trunk/net/ipv4/netfilter/ipt_iprange.c | 10 +- trunk/net/ipv4/netfilter/ipt_owner.c | 9 +- trunk/net/ipv4/netfilter/ipt_recent.c | 12 +- trunk/net/ipv4/netfilter/ipt_tos.c | 10 +- trunk/net/ipv4/netfilter/ipt_ttl.c | 11 +- trunk/net/ipv4/netfilter/iptable_filter.c | 2 +- trunk/net/ipv4/netfilter/iptable_mangle.c | 2 +- trunk/net/ipv4/netfilter/iptable_raw.c | 2 +- trunk/net/ipv4/netfilter/nf_nat_core.c | 12 +- trunk/net/ipv4/netfilter/nf_nat_helper.c | 2 +- trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c | 4 - trunk/net/ipv4/netfilter/nf_nat_proto_udp.c | 4 - trunk/net/ipv4/netfilter/nf_nat_rule.c | 8 +- trunk/net/ipv4/netfilter/nf_nat_standalone.c | 6 + trunk/net/ipv4/raw.c | 2 +- trunk/net/ipv4/route.c | 5 +- trunk/net/ipv4/tcp.c | 7 +- trunk/net/ipv4/tcp_input.c | 105 +- trunk/net/ipv4/tcp_ipv4.c | 18 +- trunk/net/ipv4/tcp_output.c | 3 +- trunk/net/ipv4/udp.c | 2 +- trunk/net/ipv4/xfrm4_mode_tunnel.c | 57 +- trunk/net/ipv4/xfrm4_policy.c | 51 +- trunk/net/ipv4/xfrm4_state.c | 1 - trunk/net/ipv6/addrconf.c | 70 +- trunk/net/ipv6/datagram.c | 2 +- trunk/net/ipv6/inet6_hashtables.c | 4 +- trunk/net/ipv6/ip6_tunnel.c | 3 +- trunk/net/ipv6/mcast.c | 2 - trunk/net/ipv6/mip6.c | 26 + trunk/net/ipv6/netfilter/Kconfig | 8 - trunk/net/ipv6/netfilter/Makefile | 1 - trunk/net/ipv6/netfilter/ip6_tables.c | 12 +- trunk/net/ipv6/netfilter/ip6t_HL.c | 17 +- trunk/net/ipv6/netfilter/ip6t_LOG.c | 15 +- trunk/net/ipv6/netfilter/ip6t_REJECT.c | 10 +- trunk/net/ipv6/netfilter/ip6t_ah.c | 8 +- trunk/net/ipv6/netfilter/ip6t_eui64.c | 8 +- trunk/net/ipv6/netfilter/ip6t_frag.c | 8 +- trunk/net/ipv6/netfilter/ip6t_hbh.c | 1 - trunk/net/ipv6/netfilter/ip6t_hl.c | 11 +- trunk/net/ipv6/netfilter/ip6t_ipv6header.c | 8 +- trunk/net/ipv6/netfilter/ip6t_mh.c | 108 - trunk/net/ipv6/netfilter/ip6t_owner.c | 8 +- trunk/net/ipv6/netfilter/ip6t_rt.c | 8 +- trunk/net/ipv6/netfilter/ip6table_filter.c | 21 +- trunk/net/ipv6/netfilter/ip6table_mangle.c | 21 +- trunk/net/ipv6/netfilter/ip6table_raw.c | 19 + trunk/net/ipv6/raw.c | 15 +- trunk/net/ipv6/route.c | 33 +- trunk/net/ipv6/sit.c | 3 +- trunk/net/ipv6/tcp_ipv6.c | 2 +- trunk/net/ipv6/udp.c | 2 +- trunk/net/ipv6/xfrm6_mode_tunnel.c | 42 +- trunk/net/ipv6/xfrm6_policy.c | 46 +- trunk/net/ipv6/xfrm6_state.c | 1 - trunk/net/ipx/af_ipx.c | 24 +- trunk/net/irda/irias_object.c | 40 - trunk/net/irda/irlan/irlan_common.c | 23 +- trunk/net/iucv/Kconfig | 15 - trunk/net/iucv/Makefile | 6 - trunk/net/iucv/af_iucv.c | 1077 ------- trunk/net/iucv/iucv.c | 1619 ---------- trunk/net/key/af_key.c | 422 --- trunk/net/netfilter/Kconfig | 39 - trunk/net/netfilter/Makefile | 2 - trunk/net/netfilter/nf_conntrack_proto_tcp.c | 40 +- trunk/net/netfilter/nf_conntrack_sane.c | 242 -- trunk/net/netfilter/xt_CLASSIFY.c | 4 +- trunk/net/netfilter/xt_CONNMARK.c | 5 +- trunk/net/netfilter/xt_CONNSECMARK.c | 6 +- trunk/net/netfilter/xt_MARK.c | 8 +- trunk/net/netfilter/xt_SECMARK.c | 4 +- trunk/net/netfilter/xt_TCPMSS.c | 296 -- trunk/net/netfilter/xt_hashlimit.c | 1 - trunk/net/packet/af_packet.c | 79 +- trunk/net/sched/act_ipt.c | 2 +- trunk/net/sched/sch_generic.c | 2 +- trunk/net/sched/sch_prio.c | 15 - trunk/net/sched/sch_sfq.c | 2 - trunk/net/socket.c | 29 +- trunk/net/wanrouter/wanmain.c | 17 +- trunk/net/x25/Makefile | 2 +- trunk/net/x25/af_x25.c | 32 +- trunk/net/x25/sysctl_net_x25.c | 8 - trunk/net/x25/x25_dev.c | 13 +- trunk/net/x25/x25_forward.c | 163 - trunk/net/x25/x25_proc.c | 98 - trunk/net/x25/x25_route.c | 3 - trunk/net/xfrm/Kconfig | 26 - trunk/net/xfrm/xfrm_algo.c | 17 - trunk/net/xfrm/xfrm_policy.c | 231 -- trunk/net/xfrm/xfrm_state.c | 184 +- trunk/net/xfrm/xfrm_user.c | 173 -- trunk/sound/Kconfig | 2 - trunk/sound/Makefile | 2 +- trunk/sound/ac97_bus.c | 4 - trunk/sound/aoa/aoa.h | 2 +- trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c | 11 +- trunk/sound/aoa/core/snd-aoa-alsa.c | 5 +- trunk/sound/aoa/core/snd-aoa-alsa.h | 2 +- trunk/sound/aoa/core/snd-aoa-core.c | 4 +- .../sound/aoa/fabrics/snd-aoa-fabric-layout.c | 13 +- trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c | 22 +- trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c | 407 ++- trunk/sound/aoa/soundbus/i2sbus/i2sbus.h | 6 - trunk/sound/arm/aaci.h | 2 +- trunk/sound/core/control.c | 42 +- trunk/sound/core/control_compat.c | 5 +- trunk/sound/core/device.c | 24 +- trunk/sound/core/hwdep.c | 19 +- trunk/sound/core/init.c | 22 +- trunk/sound/core/memalloc.c | 10 +- trunk/sound/core/misc.c | 28 - trunk/sound/core/pcm.c | 50 +- trunk/sound/core/pcm_lib.c | 5 - trunk/sound/core/pcm_memory.c | 23 - trunk/sound/core/rawmidi.c | 29 +- trunk/sound/core/seq/seq_clientmgr.c | 14 +- trunk/sound/core/seq/seq_device.c | 25 +- trunk/sound/core/seq/seq_ports.c | 51 +- trunk/sound/core/seq/seq_virmidi.c | 4 +- trunk/sound/core/sound.c | 15 +- trunk/sound/core/timer.c | 80 +- trunk/sound/drivers/Kconfig | 11 - trunk/sound/drivers/Makefile | 2 - trunk/sound/drivers/dummy.c | 2 +- trunk/sound/drivers/portman2x4.c | 876 ------ trunk/sound/drivers/serial-u16550.c | 221 +- trunk/sound/drivers/vx/vx_mixer.c | 2 +- trunk/sound/i2c/Makefile | 1 - trunk/sound/i2c/other/Makefile | 4 +- trunk/sound/i2c/other/ak4114.c | 29 +- trunk/sound/i2c/other/ak4117.c | 2 +- trunk/sound/i2c/other/ak4xxx-adda.c | 110 +- trunk/sound/i2c/other/pt2258.c | 233 -- trunk/sound/isa/Kconfig | 2 - trunk/sound/isa/ad1816a/ad1816a_lib.c | 10 +- trunk/sound/isa/ad1848/ad1848_lib.c | 6 +- trunk/sound/isa/gus/gus_main.c | 6 +- trunk/sound/isa/opl3sa2.c | 4 +- trunk/sound/isa/sb/sb16_csp.c | 61 +- trunk/sound/isa/wavefront/wavefront.c | 1 - trunk/sound/isa/wavefront/wavefront_fx.c | 812 ++++- trunk/sound/isa/wavefront/yss225.c | 2739 ----------------- trunk/sound/pci/Kconfig | 30 +- trunk/sound/pci/ac97/ac97_codec.c | 64 +- trunk/sound/pci/ac97/ac97_patch.c | 549 +--- trunk/sound/pci/ac97/ac97_patch.h | 1 - trunk/sound/pci/ac97/ak4531_codec.c | 6 +- trunk/sound/pci/als300.c | 6 +- trunk/sound/pci/atiixp.c | 31 +- trunk/sound/pci/atiixp_modem.c | 2 +- trunk/sound/pci/ca0106/ca0106_main.c | 21 +- trunk/sound/pci/ca0106/ca0106_mixer.c | 50 +- trunk/sound/pci/cs4281.c | 2 +- trunk/sound/pci/echoaudio/darla20.c | 1 - trunk/sound/pci/echoaudio/darla24.c | 1 - trunk/sound/pci/echoaudio/echo3g.c | 1 - trunk/sound/pci/echoaudio/echo3g_dsp.c | 2 +- trunk/sound/pci/echoaudio/echoaudio.c | 18 +- trunk/sound/pci/echoaudio/gina20.c | 1 - trunk/sound/pci/echoaudio/gina24.c | 1 - trunk/sound/pci/echoaudio/indigo.c | 1 - trunk/sound/pci/echoaudio/indigodj.c | 1 - trunk/sound/pci/echoaudio/indigoio.c | 1 - trunk/sound/pci/echoaudio/layla20.c | 1 - trunk/sound/pci/echoaudio/layla24.c | 1 - trunk/sound/pci/echoaudio/mia.c | 1 - trunk/sound/pci/echoaudio/mona.c | 1 - trunk/sound/pci/emu10k1/emu10k1_main.c | 616 +--- trunk/sound/pci/emu10k1/emu10k1x.c | 6 +- trunk/sound/pci/emu10k1/emufx.c | 204 +- trunk/sound/pci/emu10k1/emumixer.c | 745 +---- trunk/sound/pci/emu10k1/emupcm.c | 147 +- trunk/sound/pci/emu10k1/emuproc.c | 34 +- trunk/sound/pci/emu10k1/io.c | 104 - trunk/sound/pci/emu10k1/p16v.c | 14 +- trunk/sound/pci/emu10k1/p17v.h | 47 - trunk/sound/pci/emu10k1/voice.c | 2 +- trunk/sound/pci/ens1370.c | 154 +- trunk/sound/pci/es1938.c | 2 +- trunk/sound/pci/fm801.c | 2 +- trunk/sound/pci/hda/Makefile | 11 +- trunk/sound/pci/hda/hda_codec.c | 68 +- trunk/sound/pci/hda/hda_intel.c | 33 +- trunk/sound/pci/hda/hda_local.h | 12 +- trunk/sound/pci/hda/hda_patch.h | 6 - trunk/sound/pci/hda/patch_analog.c | 165 +- trunk/sound/pci/hda/patch_cmedia.c | 24 +- trunk/sound/pci/hda/patch_conexant.c | 1311 -------- trunk/sound/pci/hda/patch_realtek.c | 2377 ++------------ trunk/sound/pci/hda/patch_sigmatel.c | 692 ++--- trunk/sound/pci/hda/patch_via.c | 1396 --------- trunk/sound/pci/ice1712/Makefile | 2 +- trunk/sound/pci/ice1712/amp.c | 4 +- trunk/sound/pci/ice1712/amp.h | 2 +- trunk/sound/pci/ice1712/aureon.c | 186 +- trunk/sound/pci/ice1712/aureon.h | 6 +- trunk/sound/pci/ice1712/delta.c | 34 +- trunk/sound/pci/ice1712/delta.h | 2 +- trunk/sound/pci/ice1712/ews.c | 24 +- trunk/sound/pci/ice1712/ews.h | 2 +- trunk/sound/pci/ice1712/hoontech.c | 7 +- trunk/sound/pci/ice1712/hoontech.h | 2 +- trunk/sound/pci/ice1712/ice1712.c | 74 +- trunk/sound/pci/ice1712/ice1712.h | 18 +- trunk/sound/pci/ice1712/ice1724.c | 78 +- trunk/sound/pci/ice1712/juli.c | 36 +- trunk/sound/pci/ice1712/juli.h | 2 +- trunk/sound/pci/ice1712/phase.c | 76 +- trunk/sound/pci/ice1712/phase.h | 2 +- trunk/sound/pci/ice1712/pontis.c | 42 +- trunk/sound/pci/ice1712/pontis.h | 2 +- trunk/sound/pci/ice1712/prodigy192.c | 40 +- trunk/sound/pci/ice1712/prodigy192.h | 2 +- trunk/sound/pci/ice1712/revo.c | 372 +-- trunk/sound/pci/ice1712/revo.h | 13 +- trunk/sound/pci/ice1712/vt1720_mobo.c | 59 +- trunk/sound/pci/ice1712/vt1720_mobo.h | 2 +- trunk/sound/pci/ice1712/wtm.c | 542 ---- trunk/sound/pci/ice1712/wtm.h | 20 - trunk/sound/pci/intel8x0.c | 208 +- trunk/sound/pci/intel8x0m.c | 120 +- trunk/sound/pci/korg1212/korg1212.c | 45 +- trunk/sound/pci/maestro3.c | 373 ++- trunk/sound/pci/mixart/mixart_mixer.c | 4 +- trunk/sound/pci/nm256/nm256.c | 56 +- trunk/sound/pci/pcxhr/pcxhr_mixer.c | 6 +- trunk/sound/pci/rme9652/hdsp.c | 38 - trunk/sound/pci/rme9652/hdspm.c | 1324 ++------ trunk/sound/pci/trident/trident_main.c | 4 +- trunk/sound/pci/via82xx.c | 134 +- trunk/sound/pci/via82xx_modem.c | 2 +- trunk/sound/pci/vx222/vx222.c | 4 +- trunk/sound/pci/vx222/vx222_ops.c | 2 +- trunk/sound/pci/ymfpci/ymfpci_image.h | 6 +- trunk/sound/pci/ymfpci/ymfpci_main.c | 171 +- trunk/sound/pcmcia/vx/vxp_mixer.c | 2 +- trunk/sound/pcmcia/vx/vxpocket.c | 2 +- trunk/sound/soc/Kconfig | 32 - trunk/sound/soc/Makefile | 4 - trunk/sound/soc/at91/Kconfig | 32 - trunk/sound/soc/at91/Makefile | 11 - trunk/sound/soc/at91/at91-i2s.c | 720 ----- trunk/sound/soc/at91/at91-i2s.h | 27 - trunk/sound/soc/at91/at91-pcm.c | 432 --- trunk/sound/soc/at91/at91-pcm.h | 72 - trunk/sound/soc/at91/eti_b1_wm8731.c | 375 --- trunk/sound/soc/codecs/Kconfig | 15 - trunk/sound/soc/codecs/Makefile | 9 - trunk/sound/soc/codecs/ac97.c | 156 - trunk/sound/soc/codecs/ac97.h | 18 - trunk/sound/soc/codecs/wm8731.c | 758 ----- trunk/sound/soc/codecs/wm8731.h | 44 - trunk/sound/soc/codecs/wm8750.c | 1049 ------- trunk/sound/soc/codecs/wm8750.h | 67 - trunk/sound/soc/codecs/wm9712.c | 771 ----- trunk/sound/soc/codecs/wm9712.h | 14 - trunk/sound/soc/pxa/Kconfig | 60 - trunk/sound/soc/pxa/Makefile | 20 - trunk/sound/soc/pxa/corgi.c | 383 --- trunk/sound/soc/pxa/poodle.c | 352 --- trunk/sound/soc/pxa/pxa2xx-ac97.c | 431 --- trunk/sound/soc/pxa/pxa2xx-ac97.h | 22 - trunk/sound/soc/pxa/pxa2xx-i2s.c | 318 -- trunk/sound/soc/pxa/pxa2xx-i2s.h | 20 - trunk/sound/soc/pxa/pxa2xx-pcm.c | 372 --- trunk/sound/soc/pxa/pxa2xx-pcm.h | 34 - trunk/sound/soc/pxa/spitz.c | 394 --- trunk/sound/soc/pxa/tosa.c | 289 -- trunk/sound/soc/soc-core.c | 1587 ---------- trunk/sound/soc/soc-dapm.c | 1323 -------- trunk/sound/sparc/dbri.c | 2 +- trunk/sound/usb/usbaudio.c | 189 +- trunk/sound/usb/usbaudio.h | 1 - trunk/sound/usb/usbquirks.h | 32 +- 547 files changed, 11045 insertions(+), 45326 deletions(-) delete mode 100644 trunk/Documentation/sound/alsa/soc/DAI.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/clocking.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/codec.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/dapm.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/machine.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/overview.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/platform.txt delete mode 100644 trunk/Documentation/sound/alsa/soc/pops_clicks.txt create mode 100644 trunk/arch/avr32/boards/atstk1000/spi.c create mode 100644 trunk/arch/avr32/lib/libgcc.h create mode 100644 trunk/arch/avr32/lib/longlong.h delete mode 100644 trunk/crypto/camellia.c delete mode 100644 trunk/crypto/fcrypt.c delete mode 100644 trunk/crypto/pcbc.c delete mode 100644 trunk/drivers/net/atl1/Makefile delete mode 100644 trunk/drivers/net/atl1/atl1.h delete mode 100644 trunk/drivers/net/atl1/atl1_ethtool.c delete mode 100644 trunk/drivers/net/atl1/atl1_hw.c delete mode 100644 trunk/drivers/net/atl1/atl1_hw.h delete mode 100644 trunk/drivers/net/atl1/atl1_main.c delete mode 100644 trunk/drivers/net/atl1/atl1_param.c create mode 100644 trunk/drivers/s390/net/iucv.c create mode 100644 trunk/drivers/s390/net/iucv.h create mode 100644 trunk/drivers/tc/tc-driver.c delete mode 100644 trunk/include/asm-avr32/arch-at32ap/gpio.h delete mode 100644 trunk/include/asm-avr32/arch-at32ap/irq.h delete mode 100644 trunk/include/asm-avr32/gpio.h delete mode 100644 trunk/include/asm-mips/dec/tc.h delete mode 100644 trunk/include/asm-mips/dec/tcinfo.h delete mode 100644 trunk/include/asm-mips/dec/tcmodule.h delete mode 100644 trunk/include/linux/netfilter/nf_conntrack_sane.h delete mode 100644 trunk/include/linux/netfilter/xt_TCPMSS.h delete mode 100644 trunk/include/linux/netfilter_ipv6/ip6t_mh.h create mode 100644 trunk/include/linux/tc.h delete mode 100644 trunk/include/net/iucv/af_iucv.h delete mode 100644 trunk/include/net/iucv/iucv.h delete mode 100644 trunk/include/sound/pt2258.h delete mode 100644 trunk/include/sound/soc-dapm.h delete mode 100644 trunk/include/sound/soc.h create mode 100644 trunk/include/sound/typedefs.h create mode 100644 trunk/net/ipv4/netfilter/ipt_TCPMSS.c delete mode 100644 trunk/net/ipv6/netfilter/ip6t_mh.c delete mode 100644 trunk/net/iucv/Kconfig delete mode 100644 trunk/net/iucv/Makefile delete mode 100644 trunk/net/iucv/af_iucv.c delete mode 100644 trunk/net/iucv/iucv.c delete mode 100644 trunk/net/netfilter/nf_conntrack_sane.c delete mode 100644 trunk/net/netfilter/xt_TCPMSS.c delete mode 100644 trunk/net/x25/x25_forward.c delete mode 100644 trunk/sound/drivers/portman2x4.c delete mode 100644 trunk/sound/i2c/other/pt2258.c delete mode 100644 trunk/sound/isa/wavefront/yss225.c delete mode 100644 trunk/sound/pci/hda/patch_conexant.c delete mode 100644 trunk/sound/pci/hda/patch_via.c delete mode 100644 trunk/sound/pci/ice1712/wtm.c delete mode 100644 trunk/sound/pci/ice1712/wtm.h delete mode 100644 trunk/sound/soc/Kconfig delete mode 100644 trunk/sound/soc/Makefile delete mode 100644 trunk/sound/soc/at91/Kconfig delete mode 100644 trunk/sound/soc/at91/Makefile delete mode 100644 trunk/sound/soc/at91/at91-i2s.c delete mode 100644 trunk/sound/soc/at91/at91-i2s.h delete mode 100644 trunk/sound/soc/at91/at91-pcm.c delete mode 100644 trunk/sound/soc/at91/at91-pcm.h delete mode 100644 trunk/sound/soc/at91/eti_b1_wm8731.c delete mode 100644 trunk/sound/soc/codecs/Kconfig delete mode 100644 trunk/sound/soc/codecs/Makefile delete mode 100644 trunk/sound/soc/codecs/ac97.c delete mode 100644 trunk/sound/soc/codecs/ac97.h delete mode 100644 trunk/sound/soc/codecs/wm8731.c delete mode 100644 trunk/sound/soc/codecs/wm8731.h delete mode 100644 trunk/sound/soc/codecs/wm8750.c delete mode 100644 trunk/sound/soc/codecs/wm8750.h delete mode 100644 trunk/sound/soc/codecs/wm9712.c delete mode 100644 trunk/sound/soc/codecs/wm9712.h delete mode 100644 trunk/sound/soc/pxa/Kconfig delete mode 100644 trunk/sound/soc/pxa/Makefile delete mode 100644 trunk/sound/soc/pxa/corgi.c delete mode 100644 trunk/sound/soc/pxa/poodle.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-ac97.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-ac97.h delete mode 100644 trunk/sound/soc/pxa/pxa2xx-i2s.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-i2s.h delete mode 100644 trunk/sound/soc/pxa/pxa2xx-pcm.c delete mode 100644 trunk/sound/soc/pxa/pxa2xx-pcm.h delete mode 100644 trunk/sound/soc/pxa/spitz.c delete mode 100644 trunk/sound/soc/pxa/tosa.c delete mode 100644 trunk/sound/soc/soc-core.c delete mode 100644 trunk/sound/soc/soc-dapm.c diff --git a/[refs] b/[refs] index 12226912d9be..8b983c90b425 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dcb92f8804717b845db70939b523c5d152a2e0ea +refs/heads/master: b454cc6636d254fbf6049b73e9560aee76fb04a3 diff --git a/trunk/Documentation/crypto/api-intro.txt b/trunk/Documentation/crypto/api-intro.txt index e41a79aa71ce..5a03a2801d67 100644 --- a/trunk/Documentation/crypto/api-intro.txt +++ b/trunk/Documentation/crypto/api-intro.txt @@ -193,7 +193,6 @@ Original developers of the crypto algorithms: Kartikey Mahendra Bhatt (CAST6) Jon Oberheide (ARC4) Jouni Malinen (Michael MIC) - NTT(Nippon Telegraph and Telephone Corporation) (Camellia) SHA1 algorithm contributors: Jean-Francois Dive @@ -247,9 +246,6 @@ Tiger algorithm contributors: VIA PadLock contributors: Michal Ludvig -Camellia algorithm contributors: - NTT(Nippon Telegraph and Telephone Corporation) (Camellia) - Generic scatterwalk code by Adam J. Richter Please send any credits updates or corrections to: diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 4a1d8979ed92..2dc5e5da8f88 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -186,6 +186,18 @@ Who: Greg Kroah-Hartman --------------------------- +What: find_trylock_page +When: January 2007 +Why: The interface no longer has any callers left in the kernel. It + is an odd interface (compared with other find_*_page functions), in + that it does not take a refcount to the page, only the page lock. + It should be replaced with find_get_page or find_lock_page if possible. + This feature removal can be reevaluated if users of the interface + cannot cleanly use something else. +Who: Nick Piggin + +--------------------------- + What: Interrupt only SA_* flags When: Januar 2007 Why: The interrupt related SA_* flags are replaced by IRQF_* to move them diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index c30ff1bb2d10..9fef210ab50a 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -242,12 +242,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ac97_clock - AC'97 clock (default = 48000) ac97_quirk - AC'97 workaround for strange hardware See "AC97 Quirk Option" section below. - ac97_codec - Workaround to specify which AC'97 codec - instead of probing. If this works for you - file a bug with your `lspci -vn` output. - -2 -- Force probing. - -1 -- Default behavior. - 0-2 -- Use the specified codec. spdif_aclink - S/PDIF transfer over AC-link (default = 1) This module supports one card and autoprobe. @@ -785,7 +779,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. asus-dig ASUS with SPDIF out asus-dig2 ASUS with SPDIF out (using GPIO2) uniwill 3-jack - fujitsu Fujitsu Laptops (Pi1536) F1734 2-jack lg LG laptop (m1 express dual) lg-lw LG LW20/LW25 laptop @@ -807,18 +800,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ALC262 fujitsu Fujitsu Laptop hp-bpc HP xw4400/6400/8400/9400 laptops - hp-bpc-d7000 HP BPC D7000 benq Benq ED8 - hippo Hippo (ATI) with jack detection, Sony UX-90s - hippo_1 Hippo (Benq) with jack detection basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) ALC882/885 3stack-dig 3-jack with SPDIF I/O - 6stack-dig 6-jack digital with SPDIF I/O + 6stck-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 - macpro MacPro support auto auto-config reading BIOS (default) ALC883/888 @@ -828,10 +817,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 6stack-dig-demo 6-jack digital for Intel demo board acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) - medion Medion Laptops - targa-dig Targa/MSI - targa-2ch-dig Targs/MSI with 2-channel - laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) auto auto-config reading BIOS (default) ALC861/660 @@ -840,16 +825,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig 6-jack with SPDIF I/O 3stack-660 3-jack (for ALC660) uniwill-m31 Uniwill M31 laptop - toshiba Toshiba laptop support - asus Asus laptop support - asus-laptop ASUS F2/F3 laptops - auto auto-config reading BIOS (default) - - ALC861VD/660VD - 3stack 3-jack - 3stack-dig 3-jack with SPDIF OUT - 6stack-dig 6-jack with SPDIF OUT - 3stack-660 3-jack (for ALC660VD) auto auto-config reading BIOS (default) CMI9880 @@ -870,7 +845,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack 3-stack, shared surrounds laptop 2-channel only (FSC V2060, Samsung M50) laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) - ultra 2-channel with EAPD (Samsung Ultra tablet PC) AD1988 6stack 6-jack @@ -880,31 +854,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. laptop 3-jack with hp-jack automute laptop-dig ditto with SPDIF auto auto-config reading BIOS (default) - - Conexant 5045 - laptop Laptop config - test for testing/debugging purpose, almost all controls - can be adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y - - Conexant 5047 - laptop Basic Laptop config - laptop-hp Laptop config for some HP models (subdevice 30A5) - laptop-eapd Laptop config with EAPD support - test for testing/debugging purpose, almost all controls - can be adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y STAC9200/9205/9220/9221/9254 ref Reference board 3stack D945 3stack 5stack D945 5stack + SPDIF - STAC9202/9250/9251 - ref Reference board, base config - m2-2 Some Gateway MX series laptops - m6 Some Gateway NX series laptops - STAC9227/9228/9229/927x ref Reference board 3stack D965 3stack @@ -1019,7 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. * MidiMan M Audio Revolution 5.1 * MidiMan M Audio Revolution 7.1 - * MidiMan M Audio Audiophile 192 * AMP Ltd AUDIO2000 * TerraTec Aureon 5.1 Sky * TerraTec Aureon 7.1 Space @@ -1039,7 +993,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. model - Use the given board model, one of the following: revo51, revo71, amp2000, prodigy71, prodigy71lt, - prodigy192, aureon51, aureon71, universe, ap192, + prodigy192, aureon51, aureon71, universe, k8x800, phase22, phase28, ms300, av710 This module supports multiple cards and autoprobe. @@ -1095,9 +1049,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. buggy_semaphore - Enable workaround for hardwares with buggy semaphores (e.g. on some ASUS laptops) (default off) - spdif_aclink - Use S/PDIF over AC-link instead of direct connection - from the controller chip - (0 = off, 1 = on, -1 = default) This module supports one chip and autoprobe. @@ -1420,13 +1371,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. - Module snd-portman2x4 - --------------------- - - Module for Midiman Portman 2x4 parallel port MIDI interface - - This module supports multiple cards. - Module snd-powermac (on ppc only) --------------------------------- diff --git a/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl index c4d2e3507af9..1f3ae3e32d69 100644 --- a/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl @@ -36,7 +36,7 @@ Management of Cards and Devices - Card Management + Card Managment !Esound/core/init.c Device Components @@ -59,7 +59,7 @@ PCM Format Helpers !Esound/core/pcm_misc.c - PCM Memory Management + PCM Memory Managment !Esound/core/pcm_memory.c diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 74d3a35b59bc..ccd0a953953d 100644 --- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -1360,7 +1360,8 @@ substream->runtime. This runtime pointer holds the various information; it holds the copy of hw_params and sw_params configurations, the buffer - pointers, mmap records, spinlocks, etc. Almost everything you + pointers, mmap records, spinlocks, etc. Almost everyhing you need for controlling the PCM can be found there. @@ -2339,7 +2340,7 @@ struct _snd_pcm_runtime { When the PCM substreams can be synchronized (typically, - synchronized start/stop of a playback and a capture streams), + synchorinized start/stop of a playback and a capture streams), you can give SNDRV_PCM_INFO_SYNC_START, too. In this case, you'll need to check the linked-list of PCM substreams in the trigger callback. This will be @@ -3061,7 +3062,8 @@ struct _snd_pcm_runtime { Interrupt Handler Case #1 lock); @@ -3104,7 +3106,8 @@ struct _snd_pcm_runtime { Interrupt Handler Case #2 lock); @@ -3244,7 +3247,7 @@ struct _snd_pcm_runtime { You can even define your own constraint rules. For example, let's suppose my_chip can manage a substream of 1 channel if and only if the format is S16_LE, otherwise it supports any format - specified in the snd_pcm_hardware structure (or in any + specified in the snd_pcm_hardware stucture (or in any other constraint_list). You can build a rule like this: @@ -3687,6 +3690,16 @@ struct _snd_pcm_runtime { + + Here, the chip instance is retrieved via + snd_kcontrol_chip() macro. This macro + just accesses to kcontrol->private_data. The + kcontrol->private_data field is + given as the argument of snd_ctl_new() + (see the later subsection + Constructor). + + The value field is depending on the type of control as well as on info callback. For example, @@ -3767,7 +3780,7 @@ struct _snd_pcm_runtime { Like get callback, when the control has more than one elements, - all elements must be evaluated in this callback, too. + all elemehts must be evaluated in this callback, too. @@ -5528,12 +5541,12 @@ struct _snd_pcm_runtime { #ifdef CONFIG_PM static int snd_my_suspend(struct pci_dev *pci, pm_message_t state) { - .... /* do things for suspend */ + .... /* do things for suspsend */ return 0; } static int snd_my_resume(struct pci_dev *pci) { - .... /* do things for suspend */ + .... /* do things for suspsend */ return 0; } #endif @@ -6098,7 +6111,7 @@ struct _snd_pcm_runtime { - + Acknowledgments I would like to thank Phil Kerr for his help for improvement and diff --git a/trunk/Documentation/sound/alsa/hda_codec.txt b/trunk/Documentation/sound/alsa/hda_codec.txt index 4eaae2a45534..0be57ed81302 100644 --- a/trunk/Documentation/sound/alsa/hda_codec.txt +++ b/trunk/Documentation/sound/alsa/hda_codec.txt @@ -277,11 +277,11 @@ Helper Functions snd_hda_get_codec_name() stores the codec name on the given string. snd_hda_check_board_config() can be used to obtain the configuration -information matching with the device. Define the model string table -and the table with struct snd_pci_quirk entries (zero-terminated), -and pass it to the function. The function checks the modelname given -as a module parameter, and PCI subsystem IDs. If the matching entry -is found, it returns the config field value. +information matching with the device. Define the table with struct +hda_board_config entries (zero-terminated), and pass it to the +function. The function checks the modelname given as a module +parameter, and PCI subsystem IDs. If the matching entry is found, it +returns the config field value. snd_hda_add_new_ctls() can be used to create and add control entries. Pass the zero-terminated array of struct snd_kcontrol_new. The same array diff --git a/trunk/Documentation/sound/alsa/soc/DAI.txt b/trunk/Documentation/sound/alsa/soc/DAI.txt deleted file mode 100644 index 58cbfd01ea8f..000000000000 --- a/trunk/Documentation/sound/alsa/soc/DAI.txt +++ /dev/null @@ -1,56 +0,0 @@ -ASoC currently supports the three main Digital Audio Interfaces (DAI) found on -SoC controllers and portable audio CODECS today, namely AC97, I2S and PCM. - - -AC97 -==== - - AC97 is a five wire interface commonly found on many PC sound cards. It is -now also popular in many portable devices. This DAI has a reset line and time -multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines. -The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the -frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 -frame is 21uS long and is divided into 13 time slots. - -The AC97 specification can be found at :- -http://www.intel.com/design/chipsets/audio/ac97_r23.pdf - - -I2S -=== - - I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and -Rx lines are used for audio transmision, whilst the bit clock (BCLK) and -left/right clock (LRC) synchronise the link. I2S is flexible in that either the -controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock -usually varies depending on the sample rate and the master system clock -(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate -ADC and DAC LRCLK's, this allows for similtanious capture and playback at -different sample rates. - -I2S has several different operating modes:- - - o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC - transition. - - o Left Justified - MSB is transmitted on transition of LRC. - - o Right Justified - MSB is transmitted sample size BCLK's before LRC - transition. - -PCM -=== - -PCM is another 4 wire interface, very similar to I2S, that can support a more -flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used -to synchronise the link whilst the Tx and Rx lines are used to transmit and -receive the audio data. Bit clock usually varies depending on sample rate -whilst sync runs at the sample rate. PCM also supports Time Division -Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This -is sometimes referred to as network mode). - -Common PCM operating modes:- - - o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. - - o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. diff --git a/trunk/Documentation/sound/alsa/soc/clocking.txt b/trunk/Documentation/sound/alsa/soc/clocking.txt deleted file mode 100644 index e93960d53a1e..000000000000 --- a/trunk/Documentation/sound/alsa/soc/clocking.txt +++ /dev/null @@ -1,51 +0,0 @@ -Audio Clocking -============== - -This text describes the audio clocking terms in ASoC and digital audio in -general. Note: Audio clocking can be complex ! - - -Master Clock ------------- - -Every audio subsystem is driven by a master clock (sometimes refered to as MCLK -or SYSCLK). This audio master clock can be derived from a number of sources -(e.g. crystal, PLL, CPU clock) and is responsible for producing the correct -audio playback and capture sample rates. - -Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that -their speed can be altered by software (depending on the system use and to save -power). Other master clocks are fixed at at set frequency (i.e. crystals). - - -DAI Clocks ----------- -The Digital Audio Interface is usually driven by a Bit Clock (often referred to -as BCLK). This clock is used to drive the digital audio data across the link -between the codec and CPU. - -The DAI also has a frame clock to signal the start of each audio frame. This -clock is sometimes referred to as LRC (left right clock) or FRAME. This clock -runs at exactly the sample rate (LRC = Rate). - -Bit Clock can be generated as follows:- - -BCLK = MCLK / x - - or - -BCLK = LRC * x - - or - -BCLK = LRC * Channels * Word Size - -This relationship depends on the codec or SoC CPU in particular. In general -it's best to configure BCLK to the lowest possible speed (depending on your -rate, number of channels and wordsize) to save on power. - -It's also desireable to use the codec (if possible) to drive (or master) the -audio clocks as it's usually gives more accurate sample rates than the CPU. - - - diff --git a/trunk/Documentation/sound/alsa/soc/codec.txt b/trunk/Documentation/sound/alsa/soc/codec.txt deleted file mode 100644 index 48983c75aad9..000000000000 --- a/trunk/Documentation/sound/alsa/soc/codec.txt +++ /dev/null @@ -1,197 +0,0 @@ -ASoC Codec Driver -================= - -The codec driver is generic and hardware independent code that configures the -codec to provide audio capture and playback. It should contain no code that is -specific to the target platform or machine. All platform and machine specific -code should be added to the platform and machine drivers respectively. - -Each codec driver *must* provide the following features:- - - 1) Codec DAI and PCM configuration - 2) Codec control IO - using I2C, 3 Wire(SPI) or both API's - 3) Mixers and audio controls - 4) Codec audio operations - -Optionally, codec drivers can also provide:- - - 5) DAPM description. - 6) DAPM event handler. - 7) DAC Digital mute control. - -It's probably best to use this guide in conjuction with the existing codec -driver code in sound/soc/codecs/ - -ASoC Codec driver breakdown -=========================== - -1 - Codec DAI and PCM configuration ------------------------------------ -Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and -PCM's capablities and operations. This struct is exported so that it can be -registered with the core by your machine driver. - -e.g. - -struct snd_soc_codec_dai wm8731_dai = { - .name = "WM8731", - /* playback capabilities */ - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - /* capture capabilities */ - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - /* pcm operations - see section 4 below */ - .ops = { - .prepare = wm8731_pcm_prepare, - .hw_params = wm8731_hw_params, - .shutdown = wm8731_shutdown, - }, - /* DAI operations - see DAI.txt */ - .dai_ops = { - .digital_mute = wm8731_mute, - .set_sysclk = wm8731_set_dai_sysclk, - .set_fmt = wm8731_set_dai_fmt, - } -}; -EXPORT_SYMBOL_GPL(wm8731_dai); - - -2 - Codec control IO --------------------- -The codec can ususally be controlled via an I2C or SPI style interface (AC97 -combines control with data in the DAI). The codec drivers will have to provide -functions to read and write the codec registers along with supplying a register -cache:- - - /* IO control data and register cache */ - void *control_data; /* codec control (i2c/3wire) data */ - void *reg_cache; - -Codec read/write should do any data formatting and call the hardware read write -below to perform the IO. These functions are called by the core and alsa when -performing DAPM or changing the mixer:- - - unsigned int (*read)(struct snd_soc_codec *, unsigned int); - int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - -Codec hardware IO functions - usually points to either the I2C, SPI or AC97 -read/write:- - - hw_write_t hw_write; - hw_read_t hw_read; - - -3 - Mixers and audio controls ------------------------------ -All the codec mixers and audio controls can be defined using the convenience -macros defined in soc.h. - - #define SOC_SINGLE(xname, reg, shift, mask, invert) - -Defines a single control as follows:- - - xname = Control name e.g. "Playback Volume" - reg = codec register - shift = control bit(s) offset in register - mask = control bit size(s) e.g. mask of 7 = 3 bits - invert = the control is inverted - -Other macros include:- - - #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) - -A stereo control - - #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) - -A stereo control spanning 2 registers - - #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) - -Defines an single enumerated control as follows:- - - xreg = register - xshift = control bit(s) offset in register - xmask = control bit(s) size - xtexts = pointer to array of strings that describe each setting - - #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) - -Defines a stereo enumerated control - - -4 - Codec Audio Operations --------------------------- -The codec driver also supports the following alsa operations:- - -/* SoC audio ops */ -struct snd_soc_ops { - int (*startup)(struct snd_pcm_substream *); - void (*shutdown)(struct snd_pcm_substream *); - int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); - int (*hw_free)(struct snd_pcm_substream *); - int (*prepare)(struct snd_pcm_substream *); -}; - -Please refer to the alsa driver PCM documentation for details. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm - - -5 - DAPM description. ---------------------- -The Dynamic Audio Power Management description describes the codec's power -components, their relationships and registers to the ASoC core. Please read -dapm.txt for details of building the description. - -Please also see the examples in other codec drivers. - - -6 - DAPM event handler ----------------------- -This function is a callback that handles codec domain PM calls and system -domain PM calls (e.g. suspend and resume). It's used to put the codec to sleep -when not in use. - -Power states:- - - SNDRV_CTL_POWER_D0: /* full On */ - /* vref/mid, clk and osc on, active */ - - SNDRV_CTL_POWER_D1: /* partial On */ - SNDRV_CTL_POWER_D2: /* partial On */ - - SNDRV_CTL_POWER_D3hot: /* Off, with power */ - /* everything off except vref/vmid, inactive */ - - SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ - - -7 - Codec DAC digital mute control. ------------------------------------- -Most codecs have a digital mute before the DAC's that can be used to minimise -any system noise. The mute stops any digital data from entering the DAC. - -A callback can be created that is called by the core for each codec DAI when the -mute is applied or freed. - -i.e. - -static int wm8974_mute(struct snd_soc_codec *codec, - struct snd_soc_codec_dai *dai, int mute) -{ - u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf; - if(mute) - wm8974_write(codec, WM8974_DAC, mute_reg | 0x40); - else - wm8974_write(codec, WM8974_DAC, mute_reg); - return 0; -} diff --git a/trunk/Documentation/sound/alsa/soc/dapm.txt b/trunk/Documentation/sound/alsa/soc/dapm.txt deleted file mode 100644 index c11877f5b4a1..000000000000 --- a/trunk/Documentation/sound/alsa/soc/dapm.txt +++ /dev/null @@ -1,297 +0,0 @@ -Dynamic Audio Power Management for Portable Devices -=================================================== - -1. Description -============== - -Dynamic Audio Power Management (DAPM) is designed to allow portable Linux devices -to use the minimum amount of power within the audio subsystem at all times. It -is independent of other kernel PM and as such, can easily co-exist with the -other PM systems. - -DAPM is also completely transparent to all user space applications as all power -switching is done within the ASoC core. No code changes or recompiling are -required for user space applications. DAPM makes power switching descisions based -upon any audio stream (capture/playback) activity and audio mixer settings -within the device. - -DAPM spans the whole machine. It covers power control within the entire audio -subsystem, this includes internal codec power blocks and machine level power -systems. - -There are 4 power domains within DAPM - - 1. Codec domain - VREF, VMID (core codec and audio power) - Usually controlled at codec probe/remove and suspend/resume, although - can be set at stream time if power is not needed for sidetone, etc. - - 2. Platform/Machine domain - physically connected inputs and outputs - Is platform/machine and user action specific, is configured by the - machine driver and responds to asynchronous events e.g when HP - are inserted - - 3. Path domain - audio susbsystem signal paths - Automatically set when mixer and mux settings are changed by the user. - e.g. alsamixer, amixer. - - 4. Stream domain - DAC's and ADC's. - Enabled and disabled when stream playback/capture is started and - stopped respectively. e.g. aplay, arecord. - -All DAPM power switching descisons are made automatically by consulting an audio -routing map of the whole machine. This map is specific to each machine and -consists of the interconnections between every audio component (including -internal codec components). All audio components that effect power are called -widgets hereafter. - - -2. DAPM Widgets -=============== - -Audio DAPM widgets fall into a number of types:- - - o Mixer - Mixes several analog signals into a single analog signal. - o Mux - An analog switch that outputs only 1 of it's inputs. - o PGA - A programmable gain amplifier or attenuation widget. - o ADC - Analog to Digital Converter - o DAC - Digital to Analog Converter - o Switch - An analog switch - o Input - A codec input pin - o Output - A codec output pin - o Headphone - Headphone (and optional Jack) - o Mic - Mic (and optional Jack) - o Line - Line Input/Output (and optional Jack) - o Speaker - Speaker - o Pre - Special PRE widget (exec before all others) - o Post - Special POST widget (exec after all others) - -(Widgets are defined in include/sound/soc-dapm.h) - -Widgets are usually added in the codec driver and the machine driver. There are -convience macros defined in soc-dapm.h that can be used to quickly build a -list of widgets of the codecs and machines DAPM widgets. - -Most widgets have a name, register, shift and invert. Some widgets have extra -parameters for stream name and kcontrols. - - -2.1 Stream Domain Widgets -------------------------- - -Stream Widgets relate to the stream power domain and only consist of ADC's -(analog to digital converters) and DAC's (digital to analog converters). - -Stream widgets have the following format:- - -SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), - -NOTE: the stream name must match the corresponding stream name in your codecs -snd_soc_codec_dai. - -e.g. stream widgets for HiFi playback and capture - -SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), -SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), - - -2.2 Path Domain Widgets ------------------------ - -Path domain widgets have a ability to control or effect the audio signal or -audio paths within the audio subsystem. They have the following form:- - -SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) - -Any widget kcontrols can be set using the controls and num_controls members. - -e.g. Mixer widget (the kcontrols are declared first) - -/* Output Mixer */ -static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { -SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), -SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), -SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), -}; - -SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, - ARRAY_SIZE(wm8731_output_mixer_controls)), - - -2.3 Platform/Machine domain Widgets ------------------------------------ - -Machine widgets are different from codec widgets in that they don't have a -codec register bit associated with them. A machine widget is assigned to each -machine audio component (non codec) that can be independently powered. e.g. - - o Speaker Amp - o Microphone Bias - o Jack connectors - -A machine widget can have an optional call back. - -e.g. Jack connector widget for an external Mic that enables Mic Bias -when the Mic is inserted:- - -static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) -{ - if(SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); - else - reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_MIC_BIAS); - - return 0; -} - -SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), - - -2.4 Codec Domain ----------------- - -The Codec power domain has no widgets and is handled by the codecs DAPM event -handler. This handler is called when the codec powerstate is changed wrt to any -stream event or by kernel PM events. - - -2.5 Virtual Widgets -------------------- - -Sometimes widgets exist in the codec or machine audio map that don't have any -corresponding register bit for power control. In this case it's necessary to -create a virtual widget - a widget with no control bits e.g. - -SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), - -This can be used to merge to signal paths together in software. - -After all the widgets have been defined, they can then be added to the DAPM -subsystem individually with a call to snd_soc_dapm_new_control(). - - -3. Codec Widget Interconnections -================================ - -Widgets are connected to each other within the codec and machine by audio -paths (called interconnections). Each interconnection must be defined in order -to create a map of all audio paths between widgets. -This is easiest with a diagram of the codec (and schematic of the machine audio -system), as it requires joining widgets together via their audio signal paths. - -i.e. from the WM8731 codec's output mixer (wm8731.c) - -The WM8731 output mixer has 3 inputs (sources) - - 1. Line Bypass Input - 2. DAC (HiFi playback) - 3. Mic Sidetone Input - -Each input in this example has a kcontrol associated with it (defined in example -above) and is connected to the output mixer via it's kcontrol name. We can now -connect the destination widget (wrt audio signal) with it's source widgets. - - /* output mixer */ - {"Output Mixer", "Line Bypass Switch", "Line Input"}, - {"Output Mixer", "HiFi Playback Switch", "DAC"}, - {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, - -So we have :- - - Destination Widget <=== Path Name <=== Source Widget - -Or:- - - Sink, Path, Source - -Or :- - - "Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". - -When there is no path name connecting widgets (e.g. a direct connection) we -pass NULL for the path name. - -Interconnections are created with a call to:- - -snd_soc_dapm_connect_input(codec, sink, path, source); - -Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and -interconnections have been registered with the core. This causes the core to -scan the codec and machine so that the internal DAPM state matches the -physical state of the machine. - - -3.1 Machine Widget Interconnections ------------------------------------ -Machine widget interconnections are created in the same way as codec ones and -directly connect the codec pins to machine level widgets. - -e.g. connects the speaker out codec pins to the internal speaker. - - /* ext speaker connected to codec pins LOUT2, ROUT2 */ - {"Ext Spk", NULL , "ROUT2"}, - {"Ext Spk", NULL , "LOUT2"}, - -This allows the DAPM to power on and off pins that are connected (and in use) -and pins that are NC respectively. - - -4 Endpoint Widgets -=================== -An endpoint is a start or end point (widget) of an audio signal within the -machine and includes the codec. e.g. - - o Headphone Jack - o Internal Speaker - o Internal Mic - o Mic Jack - o Codec Pins - -When a codec pin is NC it can be marked as not used with a call to - -snd_soc_dapm_set_endpoint(codec, "Widget Name", 0); - -The last argument is 0 for inactive and 1 for active. This way the pin and its -input widget will never be powered up and consume power. - -This also applies to machine widgets. e.g. if a headphone is connected to a -jack then the jack can be marked active. If the headphone is removed, then -the headphone jack can be marked inactive. - - -5 DAPM Widget Events -==================== - -Some widgets can register their interest with the DAPM core in PM events. -e.g. A Speaker with an amplifier registers a widget so the amplifier can be -powered only when the spk is in use. - -/* turn speaker amplifier on/off depending on use */ -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - - return 0; -} - -/* corgi machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets = - SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); - -Please see soc-dapm.h for all other widgets that support events. - - -5.1 Event types ---------------- - -The following event types are supported by event widgets. - -/* dapm event types */ -#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ -#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ -#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ -#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ -#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ -#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ diff --git a/trunk/Documentation/sound/alsa/soc/machine.txt b/trunk/Documentation/sound/alsa/soc/machine.txt deleted file mode 100644 index 72bd222f2a21..000000000000 --- a/trunk/Documentation/sound/alsa/soc/machine.txt +++ /dev/null @@ -1,113 +0,0 @@ -ASoC Machine Driver -=================== - -The ASoC machine (or board) driver is the code that glues together the platform -and codec drivers. - -The machine driver can contain codec and platform specific code. It registers -the audio subsystem with the kernel as a platform device and is represented by -the following struct:- - -/* SoC machine */ -struct snd_soc_machine { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - - /* the pre and post PM functions are used to do any PM work before and - * after the codec and DAI's do any PM work. */ - int (*suspend_pre)(struct platform_device *pdev, pm_message_t state); - int (*suspend_post)(struct platform_device *pdev, pm_message_t state); - int (*resume_pre)(struct platform_device *pdev); - int (*resume_post)(struct platform_device *pdev); - - /* machine stream operations */ - struct snd_soc_ops *ops; - - /* CPU <--> Codec DAI links */ - struct snd_soc_dai_link *dai_link; - int num_links; -}; - -probe()/remove() ----------------- -probe/remove are optional. Do any machine specific probe here. - - -suspend()/resume() ------------------- -The machine driver has pre and post versions of suspend and resume to take care -of any machine audio tasks that have to be done before or after the codec, DAI's -and DMA is suspended and resumed. Optional. - - -Machine operations ------------------- -The machine specific audio operations can be set here. Again this is optional. - - -Machine DAI Configuration -------------------------- -The machine DAI configuration glues all the codec and CPU DAI's together. It can -also be used to set up the DAI system clock and for any machine related DAI -initialisation e.g. the machine audio map can be connected to the codec audio -map, unconnnected codec pins can be set as such. Please see corgi.c, spitz.c -for examples. - -struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. - -/* corgi digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link corgi_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8731_dai, - .init = corgi_wm8731_init, - .ops = &corgi_ops, -}; - -struct snd_soc_machine then sets up the machine with it's DAI's. e.g. - -/* corgi audio machine driver */ -static struct snd_soc_machine snd_soc_machine_corgi = { - .name = "Corgi", - .dai_link = &corgi_dai, - .num_links = 1, -}; - - -Machine Audio Subsystem ------------------------ - -The machine soc device glues the platform, machine and codec driver together. -Private data can also be set here. e.g. - -/* corgi audio private data */ -static struct wm8731_setup_data corgi_wm8731_setup = { - .i2c_address = 0x1b, -}; - -/* corgi audio subsystem */ -static struct snd_soc_device corgi_snd_devdata = { - .machine = &snd_soc_machine_corgi, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8731, - .codec_data = &corgi_wm8731_setup, -}; - - -Machine Power Map ------------------ - -The machine driver can optionally extend the codec power map and to become an -audio power map of the audio subsystem. This allows for automatic power up/down -of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack -sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for -details. - - -Machine Controls ----------------- - -Machine specific audio mixer controls can be added in the dai init function. \ No newline at end of file diff --git a/trunk/Documentation/sound/alsa/soc/overview.txt b/trunk/Documentation/sound/alsa/soc/overview.txt deleted file mode 100644 index 753c5cc5984a..000000000000 --- a/trunk/Documentation/sound/alsa/soc/overview.txt +++ /dev/null @@ -1,83 +0,0 @@ -ALSA SoC Layer -============== - -The overall project goal of the ALSA System on Chip (ASoC) layer is to provide -better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00, -iMX, etc) and portable audio codecs. Currently there is some support in the -kernel for SoC audio, however it has some limitations:- - - * Currently, codec drivers are often tightly coupled to the underlying SoC - cpu. This is not ideal and leads to code duplication i.e. Linux now has 4 - different wm8731 drivers for 4 different SoC platforms. - - * There is no standard method to signal user initiated audio events. - e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion - event. These are quite common events on portable devices and ofter require - machine specific code to re route audio, enable amps etc after such an event. - - * Current drivers tend to power up the entire codec when playing - (or recording) audio. This is fine for a PC, but tends to waste a lot of - power on portable devices. There is also no support for saving power via - changing codec oversampling rates, bias currents, etc. - - -ASoC Design -=========== - -The ASoC layer is designed to address these issues and provide the following -features :- - - * Codec independence. Allows reuse of codec drivers on other platforms - and machines. - - * Easy I2S/PCM audio interface setup between codec and SoC. Each SoC interface - and codec registers it's audio interface capabilities with the core and are - subsequently matched and configured when the application hw params are known. - - * Dynamic Audio Power Management (DAPM). DAPM automatically sets the codec to - it's minimum power state at all times. This includes powering up/down - internal power blocks depending on the internal codec audio routing and any - active streams. - - * Pop and click reduction. Pops and clicks can be reduced by powering the - codec up/down in the correct sequence (including using digital mute). ASoC - signals the codec when to change power states. - - * Machine specific controls: Allow machines to add controls to the sound card - e.g. volume control for speaker amp. - -To achieve all this, ASoC basically splits an embedded audio system into 3 -components :- - - * Codec driver: The codec driver is platform independent and contains audio - controls, audio interface capabilities, codec dapm definition and codec IO - functions. - - * Platform driver: The platform driver contains the audio dma engine and audio - interface drivers (e.g. I2S, AC97, PCM) for that platform. - - * Machine driver: The machine driver handles any machine specific controls and - audio events. i.e. turing on an amp at start of playback. - - -Documentation -============= - -The documentation is spilt into the following sections:- - -overview.txt: This file. - -codec.txt: Codec driver internals. - -DAI.txt: Description of Digital Audio Interface standards and how to configure -a DAI within your codec and CPU DAI drivers. - -dapm.txt: Dynamic Audio Power Management - -platform.txt: Platform audio DMA and DAI. - -machine.txt: Machine driver internals. - -pop_clicks.txt: How to minimise audio artifacts. - -clocking.txt: ASoC clocking for best power performance. \ No newline at end of file diff --git a/trunk/Documentation/sound/alsa/soc/platform.txt b/trunk/Documentation/sound/alsa/soc/platform.txt deleted file mode 100644 index e95b16d5a53b..000000000000 --- a/trunk/Documentation/sound/alsa/soc/platform.txt +++ /dev/null @@ -1,58 +0,0 @@ -ASoC Platform Driver -==================== - -An ASoC platform driver can be divided into audio DMA and SoC DAI configuration -and control. The platform drivers only target the SoC CPU and must have no board -specific code. - -Audio DMA -========= - -The platform DMA driver optionally supports the following alsa operations:- - -/* SoC audio ops */ -struct snd_soc_ops { - int (*startup)(struct snd_pcm_substream *); - void (*shutdown)(struct snd_pcm_substream *); - int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); - int (*hw_free)(struct snd_pcm_substream *); - int (*prepare)(struct snd_pcm_substream *); - int (*trigger)(struct snd_pcm_substream *, int); -}; - -The platform driver exports it's DMA functionailty via struct snd_soc_platform:- - -struct snd_soc_platform { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); - int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); - - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); - void (*pcm_free)(struct snd_pcm *); - - /* platform stream ops */ - struct snd_pcm_ops *pcm_ops; -}; - -Please refer to the alsa driver documentation for details of audio DMA. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c436.htm - -An example DMA driver is soc/pxa/pxa2xx-pcm.c - - -SoC DAI Drivers -=============== - -Each SoC DAI driver must provide the following features:- - - 1) Digital audio interface (DAI) description - 2) Digital audio interface configuration - 3) PCM's description - 4) Sysclk configuration - 5) Suspend and resume (optional) - -Please see codec.txt for a description of items 1 - 4. diff --git a/trunk/Documentation/sound/alsa/soc/pops_clicks.txt b/trunk/Documentation/sound/alsa/soc/pops_clicks.txt deleted file mode 100644 index 2cf7ee5b3d74..000000000000 --- a/trunk/Documentation/sound/alsa/soc/pops_clicks.txt +++ /dev/null @@ -1,52 +0,0 @@ -Audio Pops and Clicks -===================== - -Pops and clicks are unwanted audio artifacts caused by the powering up and down -of components within the audio subsystem. This is noticable on PC's when an -audio module is either loaded or unloaded (at module load time the sound card is -powered up and causes a popping noise on the speakers). - -Pops and clicks can be more frequent on portable systems with DAPM. This is -because the components within the subsystem are being dynamically powered -depending on the audio usage and this can subsequently cause a small pop or -click every time a component power state is changed. - - -Minimising Playback Pops and Clicks -=================================== - -Playback pops in portable audio subsystems cannot be completely eliminated atm, -however future audio codec hardware will have better pop and click supression. -Pops can be reduced within playback by powering the audio components in a -specific order. This order is different for startup and shutdown and follows -some basic rules:- - - Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute - - Shutdown Order :- Digital Mute --> Output PGA --> Mixers --> DAC - -This assumes that the codec PCM output path from the DAC is via a mixer and then -a PGA (programmable gain amplifier) before being output to the speakers. - - -Minimising Capture Pops and Clicks -================================== - -Capture artifacts are somewhat easier to get rid as we can delay activating the -ADC until all the pops have occured. This follows similar power rules to -playback in that components are powered in a sequence depending upon stream -startup or shutdown. - - Startup Order - Input PGA --> Mixers --> ADC - - Shutdown Order - ADC --> Mixers --> Input PGA - - -Zipper Noise -============ -An unwanted zipper noise can occur within the audio playback or capture stream -when a volume control is changed near its maximum gain value. The zipper noise -is heard when the gain increase or decrease changes the mean audio signal -amplitude too quickly. It can be minimised by enabling the zero cross setting -for each volume control. The ZC forces the gain change to occur when the signal -crosses the zero amplitude line. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f2a79481f1c1..3780623cc70c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1114,7 +1114,7 @@ S: Supported DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER P: Tobias Ringstrom M: tori@unhappy.mine.nu -L: netdev@vger.kernel.org +L: linux-kernel@vger.kernel.org S: Maintained DOCBOOK FOR DOCUMENTATION @@ -2361,7 +2361,7 @@ S: Maintained NETWORKING [WIRELESS] P: John W. Linville M: linville@tuxdriver.com -L: linux-wireless@vger.kernel.org +L: netdev@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained @@ -3037,12 +3037,6 @@ M: perex@suse.cz L: alsa-devel@alsa-project.org S: Maintained -SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT -P: Liam Girdwood -M: liam.girdwood@wolfsonmicro.com -L: alsa-devel@alsa-project.org -S: Supported - SPI SUBSYSTEM P: David Brownell M: dbrownell@users.sourceforge.net @@ -3293,6 +3287,11 @@ L: vtun@office.satix.net W: http://vtun.sourceforge.net/tun S: Maintained +TURBOCHANNEL SUBSYSTEM +P: Maciej W. Rozycki +M: macro@linux-mips.org +S: Maintained + U14-34F SCSI DRIVER P: Dario Ballabio M: ballabio_dario@emc.com diff --git a/trunk/arch/avr32/boards/atstk1000/Makefile b/trunk/arch/avr32/boards/atstk1000/Makefile index 8e0992201bb9..df9499480530 100644 --- a/trunk/arch/avr32/boards/atstk1000/Makefile +++ b/trunk/arch/avr32/boards/atstk1000/Makefile @@ -1,2 +1,2 @@ -obj-y += setup.o flash.o +obj-y += setup.o spi.o flash.o obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1002.c b/trunk/arch/avr32/boards/atstk1000/atstk1002.c index d47e39f0e971..32b361f31c2c 100644 --- a/trunk/arch/avr32/boards/atstk1000/atstk1002.c +++ b/trunk/arch/avr32/boards/atstk1000/atstk1002.c @@ -8,24 +8,17 @@ * published by the Free Software Foundation. */ #include -#include #include #include #include #include #include #include -#include #include #include -#include #include #include -#include - - -#define SW2_DEFAULT /* MMCI and UART_A available */ struct eth_addr { u8 addr[6]; @@ -36,16 +29,6 @@ static struct eth_addr __initdata hw_addr[2]; static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; -static struct spi_board_info spi_board_info[] __initdata = { - { - .modalias = "ltv350qv", - .controller_data = (void *)GPIO_PIN_PA(4), - .max_speed_hz = 16000000, - .bus_num = 0, - .chip_select = 1, - }, -}; - /* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid @@ -103,53 +86,23 @@ static void __init set_hw_addr(struct platform_device *pdev) void __init setup_board(void) { -#ifdef SW2_DEFAULT - at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ -#else - at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ -#endif - /* USART 2/unused: expansion connector */ - at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */ + at32_map_usart(1, 0); /* /dev/ttyS0 */ + at32_map_usart(2, 1); /* /dev/ttyS1 */ + at32_map_usart(3, 2); /* /dev/ttyS2 */ at32_setup_serial_console(0); } static int __init atstk1002_init(void) { - /* - * ATSTK1000 uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */ - at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */ - at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */ - at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */ - at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */ - at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */ - at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */ - at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */ - at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */ - at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */ - at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */ - at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */ - at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */ - at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */ - at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */ - at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */ - at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */ - at32_add_system_devices(); -#ifdef SW2_DEFAULT at32_add_device_usart(0); -#else at32_add_device_usart(1); -#endif at32_add_device_usart(2); set_hw_addr(at32_add_device_eth(0, ð_data[0])); - spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); diff --git a/trunk/arch/avr32/boards/atstk1000/spi.c b/trunk/arch/avr32/boards/atstk1000/spi.c new file mode 100644 index 000000000000..567726c82c6e --- /dev/null +++ b/trunk/arch/avr32/boards/atstk1000/spi.c @@ -0,0 +1,27 @@ +/* + * ATSTK1000 SPI devices + * + * Copyright (C) 2005 Atmel Norway + * + * 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. + */ +#include +#include + +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "ltv350qv", + .max_speed_hz = 16000000, + .bus_num = 0, + .chip_select = 1, + }, +}; + +static int board_init_spi(void) +{ + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); + return 0; +} +arch_initcall(board_init_spi); diff --git a/trunk/arch/avr32/kernel/cpu.c b/trunk/arch/avr32/kernel/cpu.c index 2e72fd2699df..342452ba2049 100644 --- a/trunk/arch/avr32/kernel/cpu.c +++ b/trunk/arch/avr32/kernel/cpu.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/avr32/kernel/irq.c b/trunk/arch/avr32/kernel/irq.c index fd311248c143..856f3548e664 100644 --- a/trunk/arch/avr32/kernel/irq.c +++ b/trunk/arch/avr32/kernel/irq.c @@ -57,7 +57,6 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%3d: ", i); for_each_online_cpu(cpu) seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); - seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); seq_printf(p, " %s", action->name); for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); diff --git a/trunk/arch/avr32/kernel/setup.c b/trunk/arch/avr32/kernel/setup.c index c6734aefb559..a34211601008 100644 --- a/trunk/arch/avr32/kernel/setup.c +++ b/trunk/arch/avr32/kernel/setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -175,7 +174,8 @@ static int __init parse_tag_mem_range(struct tag *tag, * Copy the data so the bootmem init code doesn't need to care * about it. */ - if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache)) + if (mem_range_next_free >= + (sizeof(mem_range_cache) / sizeof(mem_range_cache[0]))) panic("Physical memory map too complex!\n"); new = &mem_range_cache[mem_range_next_free++]; diff --git a/trunk/arch/avr32/lib/libgcc.h b/trunk/arch/avr32/lib/libgcc.h new file mode 100644 index 000000000000..5a091b5e3618 --- /dev/null +++ b/trunk/arch/avr32/lib/libgcc.h @@ -0,0 +1,33 @@ +/* Definitions for various functions 'borrowed' from gcc-3.4.3 */ + +#define BITS_PER_UNIT 8 + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +typedef float SFtype __attribute__ ((mode (SF))); +typedef float DFtype __attribute__ ((mode (DF))); +typedef int word_type __attribute__ ((mode (__word__))); + +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#define __NW(a,b) __ ## a ## si ## b +#define __NDW(a,b) __ ## a ## di ## b + +struct DWstruct {Wtype high, low;}; + +typedef union +{ + struct DWstruct s; + DWtype ll; +} DWunion; diff --git a/trunk/arch/avr32/lib/longlong.h b/trunk/arch/avr32/lib/longlong.h new file mode 100644 index 000000000000..cd5e369ac437 --- /dev/null +++ b/trunk/arch/avr32/lib/longlong.h @@ -0,0 +1,98 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This definition file 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, or (at your option) any later version. + + This definition file 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. */ + +/* Borrowed from gcc-3.4.3 */ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#define count_leading_zeros(count, x) ((count) = __builtin_clz(x)) + +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +#define udiv_qrnnd __udiv_qrnnd_c + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) + +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) diff --git a/trunk/arch/avr32/mach-at32ap/Makefile b/trunk/arch/avr32/mach-at32ap/Makefile index b21bea9af8b1..f62eb6915510 100644 --- a/trunk/arch/avr32/mach-at32ap/Makefile +++ b/trunk/arch/avr32/mach-at32ap/Makefile @@ -1,2 +1,2 @@ -obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o +obj-y += at32ap.o clock.o pio.o intc.o extint.o hsmc.o obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o diff --git a/trunk/arch/avr32/mach-at32ap/at32ap7000.c b/trunk/arch/avr32/mach-at32ap/at32ap7000.c index c1e477ec7576..48f4ef38c70e 100644 --- a/trunk/arch/avr32/mach-at32ap/at32ap7000.c +++ b/trunk/arch/avr32/mach-at32ap/at32ap7000.c @@ -496,16 +496,9 @@ static struct resource pio3_resource[] = { DEFINE_DEV(pio, 3); DEV_CLK(mck, pio3, pba, 13); -static struct resource pio4_resource[] = { - PBMEM(0xffe03800), - IRQ(17), -}; -DEFINE_DEV(pio, 4); -DEV_CLK(mck, pio4, pba, 14); - void __init at32_add_system_devices(void) { - system_manager.eim_first_irq = EIM_IRQ_BASE; + system_manager.eim_first_irq = NR_INTERNAL_IRQS; platform_device_register(&at32_sm_device); platform_device_register(&at32_intc0_device); @@ -516,7 +509,6 @@ void __init at32_add_system_devices(void) platform_device_register(&pio1_device); platform_device_register(&pio2_device); platform_device_register(&pio3_device); - platform_device_register(&pio4_device); } /* -------------------------------------------------------------------- @@ -529,7 +521,7 @@ static struct atmel_uart_data atmel_usart0_data = { }; static struct resource atmel_usart0_resource[] = { PBMEM(0xffe00c00), - IRQ(6), + IRQ(7), }; DEFINE_DEV_DATA(atmel_usart, 0); DEV_CLK(usart, atmel_usart0, pba, 4); @@ -591,7 +583,7 @@ static inline void configure_usart3_pins(void) select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ } -static struct platform_device *__initdata at32_usarts[4]; +static struct platform_device *at32_usarts[4]; void __init at32_map_usart(unsigned int hw_id, unsigned int line) { @@ -736,19 +728,12 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) /* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ -static struct resource atmel_spi0_resource[] = { +static struct resource spi0_resource[] = { PBMEM(0xffe00000), IRQ(3), }; -DEFINE_DEV(atmel_spi, 0); -DEV_CLK(spi_clk, atmel_spi0, pba, 0); - -static struct resource atmel_spi1_resource[] = { - PBMEM(0xffe00400), - IRQ(4), -}; -DEFINE_DEV(atmel_spi, 1); -DEV_CLK(spi_clk, atmel_spi1, pba, 1); +DEFINE_DEV(spi, 0); +DEV_CLK(mck, spi0, pba, 0); struct platform_device *__init at32_add_device_spi(unsigned int id) { @@ -756,33 +741,13 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) switch (id) { case 0: - pdev = &atmel_spi0_device; + pdev = &spi0_device; select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ - - /* NPCS[2:0] */ - at32_select_gpio(GPIO_PIN_PA(3), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PA(4), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PA(5), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - break; - - case 1: - pdev = &atmel_spi1_device; - select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ - select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ - select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ - - /* NPCS[2:0] */ - at32_select_gpio(GPIO_PIN_PB(2), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PB(3), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(GPIO_PIN_PB(4), - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ + select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ + select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ break; default: @@ -895,7 +860,6 @@ struct clk *at32_clock_list[] = { &pio1_mck, &pio2_mck, &pio3_mck, - &pio4_mck, &atmel_usart0_usart, &atmel_usart1_usart, &atmel_usart2_usart, @@ -904,8 +868,7 @@ struct clk *at32_clock_list[] = { &macb0_pclk, &macb1_hclk, &macb1_pclk, - &atmel_spi0_spi_clk, - &atmel_spi1_spi_clk, + &spi0_mck, &lcdc0_hclk, &lcdc0_pixclk, }; @@ -917,7 +880,6 @@ void __init at32_portmux_init(void) at32_init_pio(&pio1_device); at32_init_pio(&pio2_device); at32_init_pio(&pio3_device); - at32_init_pio(&pio4_device); } void __init at32_clock_init(void) diff --git a/trunk/arch/avr32/mach-at32ap/extint.c b/trunk/arch/avr32/mach-at32ap/extint.c index 4a60eccfebd2..b59272e81b9a 100644 --- a/trunk/arch/avr32/mach-at32ap/extint.c +++ b/trunk/arch/avr32/mach-at32ap/extint.c @@ -55,11 +55,20 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) unsigned long flags; int ret = 0; - flow_type &= IRQ_TYPE_SENSE_MASK; if (flow_type == IRQ_TYPE_NONE) flow_type = IRQ_TYPE_LEVEL_LOW; desc = &irq_desc[irq]; + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { + desc->status |= IRQ_LEVEL; + set_irq_handler(irq, handle_level_irq); + } else { + set_irq_handler(irq, handle_edge_irq); + } + spin_lock_irqsave(&sm->lock, flags); mode = sm_readl(sm, EIM_MODE); @@ -88,16 +97,9 @@ static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) break; } - if (ret == 0) { - sm_writel(sm, EIM_MODE, mode); - sm_writel(sm, EIM_EDGE, edge); - sm_writel(sm, EIM_LEVEL, level); - - if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - flow_type |= IRQ_LEVEL; - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type; - } + sm_writel(sm, EIM_MODE, mode); + sm_writel(sm, EIM_EDGE, edge); + sm_writel(sm, EIM_LEVEL, level); spin_unlock_irqrestore(&sm->lock, flags); @@ -120,6 +122,8 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) unsigned long status, pending; unsigned int i, ext_irq; + spin_lock(&sm->lock); + status = sm_readl(sm, EIM_ISR); pending = status & sm_readl(sm, EIM_IMR); @@ -129,11 +133,10 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc) ext_irq = i + sm->eim_first_irq; ext_desc = irq_desc + ext_irq; - if (ext_desc->status & IRQ_LEVEL) - handle_level_irq(ext_irq, ext_desc); - else - handle_edge_irq(ext_irq, ext_desc); + ext_desc->handle_irq(ext_irq, ext_desc); } + + spin_unlock(&sm->lock); } static int __init eim_init(void) @@ -165,9 +168,8 @@ static int __init eim_init(void) sm->eim_chip = &eim_chip; for (i = 0; i < nr_irqs; i++) { - /* NOTE the handler we set here is ignored by the demux */ set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, - handle_level_irq); + handle_edge_irq); set_irq_chip_data(sm->eim_first_irq + i, sm); } diff --git a/trunk/arch/avr32/mach-at32ap/pio.c b/trunk/arch/avr32/mach-at32ap/pio.c index 9ba5654cde11..f1280ed8ed6d 100644 --- a/trunk/arch/avr32/mach-at32ap/pio.c +++ b/trunk/arch/avr32/mach-at32ap/pio.c @@ -12,9 +12,7 @@ #include #include #include -#include -#include #include #include @@ -28,8 +26,7 @@ struct pio_device { const struct platform_device *pdev; struct clk *clk; u32 pinmux_mask; - u32 gpio_mask; - char name[8]; + char name[32]; }; static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; @@ -79,9 +76,6 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph, if (!(flags & AT32_GPIOF_PULLUP)) pio_writel(pio, PUDR, mask); - /* gpio_request NOT allowed */ - set_bit(pin_index, &pio->gpio_mask); - return; fail: @@ -105,52 +99,19 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags) goto fail; } - if (flags & AT32_GPIOF_OUTPUT) { - if (flags & AT32_GPIOF_HIGH) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); - pio_writel(pio, PUDR, mask); + pio_writel(pio, PUER, mask); + if (flags & AT32_GPIOF_HIGH) + pio_writel(pio, SODR, mask); + else + pio_writel(pio, CODR, mask); + if (flags & AT32_GPIOF_OUTPUT) pio_writel(pio, OER, mask); - } else { - if (flags & AT32_GPIOF_PULLUP) - pio_writel(pio, PUER, mask); - else - pio_writel(pio, PUDR, mask); - if (flags & AT32_GPIOF_DEGLITCH) - pio_writel(pio, IFER, mask); - else - pio_writel(pio, IFDR, mask); + else pio_writel(pio, ODR, mask); - } pio_writel(pio, PER, mask); - - /* gpio_request now allowed */ - clear_bit(pin_index, &pio->gpio_mask); - - return; - -fail: - dump_stack(); -} - -/* Reserve a pin, preventing anyone else from changing its configuration. */ -void __init at32_reserve_pin(unsigned int pin) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - goto fail; - } - - if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { - printk("%s: pin %u is busy\n", pio->name, pin_index); - goto fail; - } + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); return; @@ -158,197 +119,20 @@ void __init at32_reserve_pin(unsigned int pin) dump_stack(); } -/*--------------------------------------------------------------------------*/ - -/* GPIO API */ - -int gpio_request(unsigned int gpio, const char *label) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - if (test_and_set_bit(pin, &pio->gpio_mask)) - return -EBUSY; - - return 0; -} -EXPORT_SYMBOL(gpio_request); - -void gpio_free(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) { - printk(KERN_ERR - "gpio: attempted to free invalid pin %u\n", gpio); - return; - } - - pin = gpio & 0x1f; - if (!test_and_clear_bit(pin, &pio->gpio_mask)) - printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n", - pio->name, pin); -} -EXPORT_SYMBOL(gpio_free); - -int gpio_direction_input(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - pio_writel(pio, ODR, 1 << pin); - - return 0; -} -EXPORT_SYMBOL(gpio_direction_input); - -int gpio_direction_output(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int pin; - - pio = gpio_to_pio(gpio); - if (!pio) - return -ENODEV; - - pin = gpio & 0x1f; - pio_writel(pio, OER, 1 << pin); - - return 0; -} -EXPORT_SYMBOL(gpio_direction_output); - -int gpio_get_value(unsigned int gpio) -{ - struct pio_device *pio = &pio_dev[gpio >> 5]; - - return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1; -} -EXPORT_SYMBOL(gpio_get_value); - -void gpio_set_value(unsigned int gpio, int value) -{ - struct pio_device *pio = &pio_dev[gpio >> 5]; - u32 mask; - - mask = 1 << (gpio & 0x1f); - if (value) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); -} -EXPORT_SYMBOL(gpio_set_value); - -/*--------------------------------------------------------------------------*/ - -/* GPIO IRQ support */ - -static void gpio_irq_mask(unsigned irq) -{ - unsigned gpio = irq_to_gpio(irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IDR, 1 << (gpio & 0x1f)); -} - -static void gpio_irq_unmask(unsigned irq) -{ - unsigned gpio = irq_to_gpio(irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IER, 1 << (gpio & 0x1f)); -} - -static int gpio_irq_type(unsigned irq, unsigned type) -{ - if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) - return -EINVAL; - - return 0; -} - -static struct irq_chip gpio_irqchip = { - .name = "gpio", - .mask = gpio_irq_mask, - .unmask = gpio_irq_unmask, - .set_type = gpio_irq_type, -}; - -static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct pio_device *pio = get_irq_chip_data(irq); - unsigned gpio_irq; - - gpio_irq = (unsigned) get_irq_data(irq); - for (;;) { - u32 isr; - struct irq_desc *d; - - /* ack pending GPIO interrupts */ - isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); - if (!isr) - break; - do { - int i; - - i = ffs(isr) - 1; - isr &= ~(1 << i); - - i += gpio_irq; - d = &irq_desc[i]; - - d->handle_irq(i, d); - } while (isr); - } -} - -static void __init -gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) -{ - unsigned i; - - set_irq_chip_data(irq, pio); - set_irq_data(irq, (void *) gpio_irq); - - for (i = 0; i < 32; i++, gpio_irq++) { - set_irq_chip_data(gpio_irq, pio); - set_irq_chip_and_handler(gpio_irq, &gpio_irqchip, - handle_simple_irq); - } - - set_irq_chained_handler(irq, gpio_irq_handler); -} - -/*--------------------------------------------------------------------------*/ - static int __init pio_probe(struct platform_device *pdev) { struct pio_device *pio = NULL; - int irq = platform_get_irq(pdev, 0); - int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32; BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); pio = &pio_dev[pdev->id]; BUG_ON(!pio->regs); - gpio_irq_setup(pio, irq, gpio_irq_base); + /* TODO: Interrupts */ platform_set_drvdata(pdev, pio); - printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n", - pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31); + printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n", + pio->name, pio->regs, platform_get_irq(pdev, 0)); return 0; } @@ -364,7 +148,7 @@ static int __init pio_init(void) { return platform_driver_register(&pio_driver); } -postcore_initcall(pio_init); +subsys_initcall(pio_init); void __init at32_init_pio(struct platform_device *pdev) { @@ -400,13 +184,6 @@ void __init at32_init_pio(struct platform_device *pdev) pio->pdev = pdev; pio->regs = ioremap(regs->start, regs->end - regs->start + 1); - /* - * request_gpio() is only valid for pins that have been - * explicitly configured as GPIO and not previously requested - */ - pio->gpio_mask = ~0UL; - - /* start with irqs disabled and acked */ - pio_writel(pio, IDR, ~0UL); - (void) pio_readl(pio, ISR); + pio_writel(pio, ODR, ~0UL); + pio_writel(pio, PER, ~0UL); } diff --git a/trunk/arch/avr32/mm/cache.c b/trunk/arch/avr32/mm/cache.c index fb13f72e9a02..450515b245a0 100644 --- a/trunk/arch/avr32/mm/cache.c +++ b/trunk/arch/avr32/mm/cache.c @@ -22,34 +22,18 @@ void invalidate_dcache_region(void *start, size_t size) { - unsigned long v, begin, end, linesz, mask; - int flush = 0; + unsigned long v, begin, end, linesz; linesz = boot_cpu_data.dcache.linesz; - mask = linesz - 1; - - /* when first and/or last cachelines are shared, flush them - * instead of invalidating ... never discard valid data! - */ - begin = (unsigned long)start; - end = begin + size - 1; - - if (begin & mask) { - flush_dcache_line(start); - begin += linesz; - flush = 1; - } - if ((end & mask) != mask) { - flush_dcache_line((void *)end); - end -= linesz; - flush = 1; - } - /* remaining cachelines only need invalidation */ - for (v = begin; v <= end; v += linesz) + //printk("invalidate dcache: %p + %u\n", start, size); + + /* You asked for it, you got it */ + begin = (unsigned long)start & ~(linesz - 1); + end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); + + for (v = begin; v < end; v += linesz) invalidate_dcache_line((void *)v); - if (flush) - flush_write_buffer(); } void clean_dcache_region(void *start, size_t size) diff --git a/trunk/arch/i386/kernel/hpet.c b/trunk/arch/i386/kernel/hpet.c index 0b29d41322a2..45a8685bb60b 100644 --- a/trunk/arch/i386/kernel/hpet.c +++ b/trunk/arch/i386/kernel/hpet.c @@ -12,7 +12,7 @@ /* FSEC = 10^-15 NSEC = 10^-9 */ #define FSEC_PER_NSEC 1000000 -static void __iomem *hpet_ptr; +static void *hpet_ptr; static cycle_t read_hpet(void) { @@ -40,7 +40,8 @@ static int __init init_hpet_clocksource(void) return -ENODEV; /* calculate the hpet address: */ - hpet_base = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); + hpet_base = + (void __iomem*)ioremap_nocache(hpet_address, HPET_MMAP_SIZE); hpet_ptr = hpet_base + HPET_COUNTER; /* calculate the frequency: */ diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index ba8d302a0b72..5592fa6e1fa1 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -126,7 +126,7 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i */ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) { - volatile struct io_apic __iomem *io_apic = io_apic_base(apic); + volatile struct io_apic *io_apic = io_apic_base(apic); if (sis_apic_bug) writel(reg, &io_apic->index); writel(value, &io_apic->data); diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index e223b1d4981c..ad91528bdc14 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -224,7 +224,7 @@ void global_flush_tlb(void) list_replace_init(&df_list, &l); spin_unlock_irq(&cpa_lock); if (!cpu_has_clflush) - flush_map(NULL); + flush_map(0); list_for_each_entry_safe(pg, next, &l, lru) { if (cpu_has_clflush) flush_map(page_address(pg)); diff --git a/trunk/arch/ia64/kernel/crash.c b/trunk/arch/ia64/kernel/crash.c index 37bb16f07fc3..9d92097ce96d 100644 --- a/trunk/arch/ia64/kernel/crash.c +++ b/trunk/arch/ia64/kernel/crash.c @@ -52,7 +52,7 @@ extern void ia64_dump_cpu_regs(void *); static DEFINE_PER_CPU(struct elf_prstatus, elf_prstatus); void -crash_save_this_cpu(void) +crash_save_this_cpu() { void *buf; unsigned long cfm, sof, sol; diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 55ddd809b02d..f4c7f7769cf7 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -221,13 +221,13 @@ send_IPI_self (int op) #ifdef CONFIG_KEXEC void -kdump_smp_send_stop(void) +kdump_smp_send_stop() { send_IPI_allbutself(IPI_KDUMP_CPU_STOP); } void -kdump_smp_send_init(void) +kdump_smp_send_init() { unsigned int cpu, self_cpu; self_cpu = smp_processor_id(); diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index 67d617b60a23..b43466ba8096 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -149,8 +149,7 @@ static int cbe_nr_iommus; static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte, long n_ptes) { - unsigned long __iomem *reg; - unsigned long val; + unsigned long *reg, val; long n; reg = iommu->xlate_regs + IOC_IOPT_CacheInvd; @@ -593,7 +592,7 @@ static void __init cell_iommu_init_one(struct device_node *np, unsigned long off /* Init base fields */ i = cbe_nr_iommus++; iommu = &iommus[i]; - iommu->stab = NULL; + iommu->stab = 0; iommu->nid = nid; snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i); INIT_LIST_HEAD(&iommu->windows); diff --git a/trunk/arch/powerpc/platforms/celleb/pci.c b/trunk/arch/powerpc/platforms/celleb/pci.c index 98de836dfed3..867f83a7d0c9 100644 --- a/trunk/arch/powerpc/platforms/celleb/pci.c +++ b/trunk/arch/powerpc/platforms/celleb/pci.c @@ -65,13 +65,13 @@ static inline u8 celleb_fake_config_readb(void *addr) static inline u16 celleb_fake_config_readw(void *addr) { - __le16 *p = addr; + u16 *p = addr; return le16_to_cpu(*p); } static inline u32 celleb_fake_config_readl(void *addr) { - __le32 *p = addr; + u32 *p = addr; return le32_to_cpu(*p); } @@ -83,16 +83,16 @@ static inline void celleb_fake_config_writeb(u32 val, void *addr) static inline void celleb_fake_config_writew(u32 val, void *addr) { - __le16 val16; - __le16 *p = addr; + u16 val16; + u16 *p = addr; val16 = cpu_to_le16(val); *p = val16; } static inline void celleb_fake_config_writel(u32 val, void *addr) { - __le32 val32; - __le32 *p = addr; + u32 val32; + u32 *p = addr; val32 = cpu_to_le32(val); *p = val32; } diff --git a/trunk/arch/powerpc/platforms/celleb/scc_epci.c b/trunk/arch/powerpc/platforms/celleb/scc_epci.c index c11b39c3776a..0edbc0c4f338 100644 --- a/trunk/arch/powerpc/platforms/celleb/scc_epci.c +++ b/trunk/arch/powerpc/platforms/celleb/scc_epci.c @@ -47,7 +47,7 @@ #if 0 /* test code for epci dummy read */ static void celleb_epci_dummy_read(struct pci_dev *dev) { - void __iomem *epci_base; + void *epci_base; struct device_node *node; struct pci_controller *hose; u32 val; @@ -58,7 +58,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev) if (!hose) return; - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; val = in_be32(epci_base + SCC_EPCI_WATRP); iosync(); @@ -71,18 +71,18 @@ static inline void clear_and_disable_master_abort_interrupt( struct pci_controller *hose) { void __iomem *addr; - addr = hose->cfg_addr + PCI_COMMAND; + addr = (void *)hose->cfg_addr + PCI_COMMAND; out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16)); } static int celleb_epci_check_abort(struct pci_controller *hose, - void __iomem *addr) + unsigned long addr) { void __iomem *reg, *epci_base; u32 val; iob(); - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; reg = epci_base + PCI_COMMAND; val = in_be32(reg); @@ -108,23 +108,23 @@ static int celleb_epci_check_abort(struct pci_controller *hose, return PCIBIOS_SUCCESSFUL; } -static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, +static unsigned long celleb_epci_make_config_addr(struct pci_controller *hose, unsigned int devfn, int where) { - void __iomem *addr; + unsigned long addr; struct pci_bus *bus = hose->bus; if (bus->self) - addr = hose->cfg_data + + addr = (unsigned long)hose->cfg_data + (((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | (where & 0xff) | 0x01000000); else - addr = hose->cfg_data + + addr = (unsigned long)hose->cfg_data + (((devfn & 0xff) << 8) | (where & 0xff)); - pr_debug("EPCI: config_addr = 0x%p\n", addr); + pr_debug("EPCI: config_addr = 0x%016lx\n", addr); return addr; } @@ -132,7 +132,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose, static int celleb_epci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { - void __iomem *addr; + unsigned long addr; struct device_node *node; struct pci_controller *hose; @@ -148,17 +148,17 @@ static int celleb_epci_read_config(struct pci_bus *bus, if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + addr = (unsigned long)hose->cfg_addr + where; switch (size) { case 1: - *val = in_8(addr); + *val = in_8((u8 *)addr); break; case 2: - *val = in_be16(addr); + *val = in_be16((u16 *)addr); break; case 4: - *val = in_be32(addr); + *val = in_be32((u32 *)addr); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -171,13 +171,13 @@ static int celleb_epci_read_config(struct pci_bus *bus, switch (size) { case 1: - *val = in_8(addr); + *val = in_8((u8 *)addr); break; case 2: - *val = in_le16(addr); + *val = in_le16((u16 *)addr); break; case 4: - *val = in_le32(addr); + *val = in_le32((u32 *)addr); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -188,13 +188,13 @@ static int celleb_epci_read_config(struct pci_bus *bus, "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n", addr, devfn, where, size, *val); - return celleb_epci_check_abort(hose, NULL); + return celleb_epci_check_abort(hose, 0); } static int celleb_epci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - void __iomem *addr; + unsigned long addr; struct device_node *node; struct pci_controller *hose; @@ -210,17 +210,17 @@ static int celleb_epci_write_config(struct pci_bus *bus, if (bus->number == hose->first_busno && devfn == 0) { /* EPCI controller self */ - addr = hose->cfg_addr + where; + addr = (unsigned long)hose->cfg_addr + where; switch (size) { case 1: - out_8(addr, val); + out_8((u8 *)addr, val); break; case 2: - out_be16(addr, val); + out_be16((u16 *)addr, val); break; case 4: - out_be32(addr, val); + out_be32((u32 *)addr, val); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -233,13 +233,13 @@ static int celleb_epci_write_config(struct pci_bus *bus, switch (size) { case 1: - out_8(addr, val); + out_8((u8 *)addr, val); break; case 2: - out_le16(addr, val); + out_le16((u16 *)addr, val); break; case 4: - out_le32(addr, val); + out_le32((u32 *)addr, val); break; default: return PCIBIOS_DEVICE_NOT_FOUND; @@ -261,7 +261,7 @@ static int __devinit celleb_epci_init(struct pci_controller *hose) void __iomem *reg, *epci_base; int hwres = 0; - epci_base = hose->cfg_addr; + epci_base = (void *)hose->cfg_addr; /* PCI core reset(Internal bus and PCI clock) */ reg = epci_base + SCC_EPCI_CKCTRL; diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 117c9a0055bd..e1f51d455984 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -75,7 +75,7 @@ extern irqreturn_t xmon_irq(int, void *); extern unsigned long loops_per_jiffy; /* To be replaced by RTAS when available */ -static unsigned int __iomem *briq_SPOR; +static unsigned int *briq_SPOR; #ifdef CONFIG_SMP extern struct smp_ops_t chrp_smp_ops; @@ -267,7 +267,7 @@ void __init chrp_setup_arch(void) } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) { _chrp_type = _CHRP_briq; /* Map the SPOR register on briq and change the restart hook */ - briq_SPOR = ioremap(0xff0000e8, 4); + briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4); ppc_md.restart = briq_restart; } else { /* Let's assume it is an IBM chrp if all else fails */ diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index 631c30095617..bb17283275aa 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -194,7 +194,6 @@ int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, return result; } -EXPORT_SYMBOL_GPL(ps3_alloc_io_irq); int ps3_free_io_irq(unsigned int virq) { @@ -210,7 +209,6 @@ int ps3_free_io_irq(unsigned int virq) return result; } -EXPORT_SYMBOL_GPL(ps3_free_io_irq); /** * ps3_alloc_event_irq - Allocate a virq for use with a system event. diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/arch/powerpc/platforms/ps3/system-bus.c index a9f7e4a39a2a..bce6136cbce7 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/arch/powerpc/platforms/ps3/system-bus.c @@ -57,7 +57,6 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r) dump_mmio_region(r); return result; } -EXPORT_SYMBOL_GPL(ps3_mmio_region_create); int ps3_free_mmio_region(struct ps3_mmio_region *r) { @@ -73,7 +72,6 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r) r->lpar_addr = 0; return result; } -EXPORT_SYMBOL_GPL(ps3_free_mmio_region); static int ps3_system_bus_match(struct device *_dev, struct device_driver *_drv) diff --git a/trunk/arch/powerpc/xmon/spu-dis.c b/trunk/arch/powerpc/xmon/spu-dis.c index e5f89837c82e..ee929c641bf3 100644 --- a/trunk/arch/powerpc/xmon/spu-dis.c +++ b/trunk/arch/powerpc/xmon/spu-dis.c @@ -85,7 +85,7 @@ get_index_for_opcode (unsigned int insn) if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0) return index; - return NULL; + return 0; } /* Print a Spu instruction. */ diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 1406400bf3ea..7c621b8ef683 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -179,8 +179,6 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set CONFIG_NET_KEY=y -CONFIG_IUCV=m -CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -510,6 +508,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_LCS=m CONFIG_CTC=m +CONFIG_IUCV=m # CONFIG_NETIUCV is not set # CONFIG_SMSGIUCV is not set # CONFIG_CLAW is not set diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index 086fcec44720..918b4d845f93 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -149,15 +149,6 @@ config CRYPTO_CBC CBC: Cipher Block Chaining mode This block cipher algorithm is required for IPSec. -config CRYPTO_PCBC - tristate "PCBC support" - select CRYPTO_BLKCIPHER - select CRYPTO_MANAGER - default m - help - PCBC: Propagating Cipher Block Chaining mode - This block cipher algorithm is required for RxRPC. - config CRYPTO_LRW tristate "LRW support (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -177,13 +168,6 @@ config CRYPTO_DES help DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). -config CRYPTO_FCRYPT - tristate "FCrypt cipher algorithm" - select CRYPTO_ALGAPI - select CRYPTO_BLKCIPHER - help - FCrypt algorithm used by RxRPC. - config CRYPTO_BLOWFISH tristate "Blowfish cipher algorithm" select CRYPTO_ALGAPI @@ -425,21 +409,6 @@ config CRYPTO_CRC32C See Castagnoli93. This implementation uses lib/libcrc32c. Module will be crc32c. -config CRYPTO_CAMELLIA - tristate "Camellia cipher algorithms" - depends on CRYPTO - select CRYPTO_ALGAPI - help - Camellia cipher algorithms module. - - Camellia is a symmetric key block cipher developed jointly - at NTT and Mitsubishi Electric Corporation. - - The Camellia specifies three key sizes: 128, 192 and 256 bits. - - See also: - - config CRYPTO_TEST tristate "Testing module" depends on m diff --git a/trunk/crypto/Makefile b/trunk/crypto/Makefile index 12f93f578171..60e3d24f61f5 100644 --- a/trunk/crypto/Makefile +++ b/trunk/crypto/Makefile @@ -27,16 +27,13 @@ obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o obj-$(CONFIG_CRYPTO_ECB) += ecb.o obj-$(CONFIG_CRYPTO_CBC) += cbc.o -obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o obj-$(CONFIG_CRYPTO_LRW) += lrw.o obj-$(CONFIG_CRYPTO_DES) += des.o -obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o obj-$(CONFIG_CRYPTO_AES) += aes.o -obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o obj-$(CONFIG_CRYPTO_CAST5) += cast5.o obj-$(CONFIG_CRYPTO_CAST6) += cast6.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o diff --git a/trunk/crypto/algapi.c b/trunk/crypto/algapi.c index f7d2185b2c8f..c91530021e9c 100644 --- a/trunk/crypto/algapi.c +++ b/trunk/crypto/algapi.c @@ -377,8 +377,7 @@ void crypto_drop_spawn(struct crypto_spawn *spawn) } EXPORT_SYMBOL_GPL(crypto_drop_spawn); -struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, - u32 mask) +struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn) { struct crypto_alg *alg; struct crypto_alg *alg2; @@ -397,18 +396,10 @@ struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, return ERR_PTR(-EAGAIN); } - tfm = ERR_PTR(-EINVAL); - if (unlikely((alg->cra_flags ^ type) & mask)) - goto out_put_alg; - - tfm = __crypto_alloc_tfm(alg, type, mask); + tfm = __crypto_alloc_tfm(alg, 0); if (IS_ERR(tfm)) - goto out_put_alg; - - return tfm; + crypto_mod_put(alg); -out_put_alg: - crypto_mod_put(alg); return tfm; } EXPORT_SYMBOL_GPL(crypto_spawn_tfm); diff --git a/trunk/crypto/api.c b/trunk/crypto/api.c index 55af8bb0f050..8c446871cd5b 100644 --- a/trunk/crypto/api.c +++ b/trunk/crypto/api.c @@ -212,12 +212,31 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) } EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup); -static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) { - const struct crypto_type *type_obj = tfm->__crt_alg->cra_type; + tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK; + flags &= ~CRYPTO_TFM_REQ_MASK; + + switch (crypto_tfm_alg_type(tfm)) { + case CRYPTO_ALG_TYPE_CIPHER: + return crypto_init_cipher_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_DIGEST: + return crypto_init_digest_flags(tfm, flags); + + case CRYPTO_ALG_TYPE_COMPRESS: + return crypto_init_compress_flags(tfm, flags); + } + + return 0; +} - if (type_obj) - return type_obj->init(tfm, type, mask); +static int crypto_init_ops(struct crypto_tfm *tfm) +{ + const struct crypto_type *type = tfm->__crt_alg->cra_type; + + if (type) + return type->init(tfm); switch (crypto_tfm_alg_type(tfm)) { case CRYPTO_ALG_TYPE_CIPHER: @@ -266,29 +285,29 @@ static void crypto_exit_ops(struct crypto_tfm *tfm) } } -static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask) +static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) { - const struct crypto_type *type_obj = alg->cra_type; + const struct crypto_type *type = alg->cra_type; unsigned int len; len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1); - if (type_obj) - return len + type_obj->ctxsize(alg, type, mask); + if (type) + return len + type->ctxsize(alg); switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { default: BUG(); case CRYPTO_ALG_TYPE_CIPHER: - len += crypto_cipher_ctxsize(alg); + len += crypto_cipher_ctxsize(alg, flags); break; case CRYPTO_ALG_TYPE_DIGEST: - len += crypto_digest_ctxsize(alg); + len += crypto_digest_ctxsize(alg, flags); break; case CRYPTO_ALG_TYPE_COMPRESS: - len += crypto_compress_ctxsize(alg); + len += crypto_compress_ctxsize(alg, flags); break; } @@ -303,21 +322,24 @@ void crypto_shoot_alg(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_shoot_alg); -struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, - u32 mask) +struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags) { struct crypto_tfm *tfm = NULL; unsigned int tfm_size; int err = -ENOMEM; - tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask); + tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); tfm = kzalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_err; tfm->__crt_alg = alg; - err = crypto_init_ops(tfm, type, mask); + err = crypto_init_flags(tfm, flags); + if (err) + goto out_free_tfm; + + err = crypto_init_ops(tfm); if (err) goto out_free_tfm; @@ -340,6 +362,31 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, } EXPORT_SYMBOL_GPL(__crypto_alloc_tfm); +struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) +{ + struct crypto_tfm *tfm = NULL; + int err; + + do { + struct crypto_alg *alg; + + alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC); + err = PTR_ERR(alg); + if (IS_ERR(alg)) + continue; + + tfm = __crypto_alloc_tfm(alg, flags); + err = 0; + if (IS_ERR(tfm)) { + crypto_mod_put(alg); + err = PTR_ERR(tfm); + tfm = NULL; + } + } while (err == -EAGAIN && !signal_pending(current)); + + return tfm; +} + /* * crypto_alloc_base - Locate algorithm and allocate transform * @alg_name: Name of algorithm @@ -373,7 +420,7 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask) goto err; } - tfm = __crypto_alloc_tfm(alg, type, mask); + tfm = __crypto_alloc_tfm(alg, 0); if (!IS_ERR(tfm)) return tfm; @@ -419,6 +466,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm) kfree(tfm); } +EXPORT_SYMBOL_GPL(crypto_alloc_tfm); EXPORT_SYMBOL_GPL(crypto_free_tfm); int crypto_has_alg(const char *name, u32 type, u32 mask) diff --git a/trunk/crypto/blkcipher.c b/trunk/crypto/blkcipher.c index b5befe8c3a96..6e93004f2181 100644 --- a/trunk/crypto/blkcipher.c +++ b/trunk/crypto/blkcipher.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -314,9 +313,6 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc, struct crypto_blkcipher *tfm = desc->tfm; unsigned int alignmask = crypto_blkcipher_alignmask(tfm); - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - walk->nbytes = walk->total; if (unlikely(!walk->total)) return 0; @@ -349,8 +345,7 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, return cipher->setkey(tfm, key, keylen); } -static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, - u32 mask) +static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg) { struct blkcipher_alg *cipher = &alg->cra_blkcipher; unsigned int len = alg->cra_ctxsize; @@ -363,7 +358,7 @@ static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type, return len; } -static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm) { struct blkcipher_tfm *crt = &tfm->crt_blkcipher; struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; diff --git a/trunk/crypto/camellia.c b/trunk/crypto/camellia.c deleted file mode 100644 index 6877ecfd90bb..000000000000 --- a/trunk/crypto/camellia.c +++ /dev/null @@ -1,1801 +0,0 @@ -/* - * Copyright (C) 2006 - * NTT (Nippon Telegraph and Telephone Corporation). - * - * 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. - */ - -/* - * Algorithm Specification - * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html - */ - -/* - * - * NOTE --- NOTE --- NOTE --- NOTE - * This implementation assumes that all memory addresses passed - * as parameters are four-byte aligned. - * - */ - -#include -#include -#include -#include -#include - - -#define CAMELLIA_MIN_KEY_SIZE 16 -#define CAMELLIA_MAX_KEY_SIZE 32 -#define CAMELLIA_BLOCK_SIZE 16 -#define CAMELLIA_TABLE_BYTE_LEN 272 -#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) - -typedef u32 KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; - - -/* key constants */ - -#define CAMELLIA_SIGMA1L (0xA09E667FL) -#define CAMELLIA_SIGMA1R (0x3BCC908BL) -#define CAMELLIA_SIGMA2L (0xB67AE858L) -#define CAMELLIA_SIGMA2R (0x4CAA73B2L) -#define CAMELLIA_SIGMA3L (0xC6EF372FL) -#define CAMELLIA_SIGMA3R (0xE94F82BEL) -#define CAMELLIA_SIGMA4L (0x54FF53A5L) -#define CAMELLIA_SIGMA4R (0xF1D36F1CL) -#define CAMELLIA_SIGMA5L (0x10E527FAL) -#define CAMELLIA_SIGMA5R (0xDE682D1DL) -#define CAMELLIA_SIGMA6L (0xB05688C2L) -#define CAMELLIA_SIGMA6R (0xB3E6C1FDL) - -struct camellia_ctx { - int key_length; - KEY_TABLE_TYPE key_table; -}; - - -/* - * macros - */ - - -# define GETU32(pt) (((u32)(pt)[0] << 24) \ - ^ ((u32)(pt)[1] << 16) \ - ^ ((u32)(pt)[2] << 8) \ - ^ ((u32)(pt)[3])) - -#define COPY4WORD(dst, src) \ - do { \ - (dst)[0]=(src)[0]; \ - (dst)[1]=(src)[1]; \ - (dst)[2]=(src)[2]; \ - (dst)[3]=(src)[3]; \ - }while(0) - -#define SWAP4WORD(word) \ - do { \ - CAMELLIA_SWAP4((word)[0]); \ - CAMELLIA_SWAP4((word)[1]); \ - CAMELLIA_SWAP4((word)[2]); \ - CAMELLIA_SWAP4((word)[3]); \ - }while(0) - -#define XOR4WORD(a, b)/* a = a ^ b */ \ - do { \ - (a)[0]^=(b)[0]; \ - (a)[1]^=(b)[1]; \ - (a)[2]^=(b)[2]; \ - (a)[3]^=(b)[3]; \ - }while(0) - -#define XOR4WORD2(a, b, c)/* a = b ^ c */ \ - do { \ - (a)[0]=(b)[0]^(c)[0]; \ - (a)[1]=(b)[1]^(c)[1]; \ - (a)[2]=(b)[2]^(c)[2]; \ - (a)[3]=(b)[3]^(c)[3]; \ - }while(0) - -#define CAMELLIA_SUBKEY_L(INDEX) (subkey[(INDEX)*2]) -#define CAMELLIA_SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1]) - -/* rotation right shift 1byte */ -#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) -/* rotation left shift 1bit */ -#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) -/* rotation left shift 1byte */ -#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) - -#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - ll = (ll << bits) + (lr >> (32 - bits)); \ - lr = (lr << bits) + (rl >> (32 - bits)); \ - rl = (rl << bits) + (rr >> (32 - bits)); \ - rr = (rr << bits) + (w0 >> (32 - bits)); \ - } while(0) - -#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - w1 = lr; \ - ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ - lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ - rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ - rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ - } while(0) - -#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) -#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) -#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) -#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) - -#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - il = xl ^ kl; \ - ir = xr ^ kr; \ - t0 = il >> 16; \ - t1 = ir >> 16; \ - yl = CAMELLIA_SP1110(ir & 0xff) \ - ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ - ^ CAMELLIA_SP3033(t1 & 0xff) \ - ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ - yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ - ^ CAMELLIA_SP0222(t0 & 0xff) \ - ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(il & 0xff); \ - yl ^= yr; \ - yr = CAMELLIA_RR8(yr); \ - yr ^= yl; \ - } while(0) - - -/* - * for speed up - * - */ -#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ - do { \ - t0 = kll; \ - t2 = krr; \ - t0 &= ll; \ - t2 |= rr; \ - rl ^= t2; \ - lr ^= CAMELLIA_RL1(t0); \ - t3 = krl; \ - t1 = klr; \ - t3 &= rl; \ - t1 |= lr; \ - ll ^= t1; \ - rr ^= CAMELLIA_RL1(t3); \ - } while(0) - -#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - ir = CAMELLIA_SP1110(xr & 0xff); \ - il = CAMELLIA_SP1110((xl>>24) & 0xff); \ - ir ^= CAMELLIA_SP0222((xr>>24) & 0xff); \ - il ^= CAMELLIA_SP0222((xl>>16) & 0xff); \ - ir ^= CAMELLIA_SP3033((xr>>16) & 0xff); \ - il ^= CAMELLIA_SP3033((xl>>8) & 0xff); \ - ir ^= CAMELLIA_SP4404((xr>>8) & 0xff); \ - il ^= CAMELLIA_SP4404(xl & 0xff); \ - il ^= kl; \ - ir ^= il ^ kr; \ - yl ^= ir; \ - yr ^= CAMELLIA_RR8(il) ^ ir; \ - } while(0) - -/** - * Stuff related to the Camellia key schedule - */ -#define SUBL(x) subL[(x)] -#define SUBR(x) subR[(x)] - - -static const u32 camellia_sp1110[256] = { - 0x70707000,0x82828200,0x2c2c2c00,0xececec00, - 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, - 0xe4e4e400,0x85858500,0x57575700,0x35353500, - 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, - 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, - 0x45454500,0x19191900,0xa5a5a500,0x21212100, - 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, - 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, - 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, - 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, - 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, - 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, - 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, - 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, - 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, - 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, - 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, - 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, - 0x74747400,0x12121200,0x2b2b2b00,0x20202000, - 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, - 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, - 0x34343400,0x7e7e7e00,0x76767600,0x05050500, - 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, - 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, - 0x14141400,0x58585800,0x3a3a3a00,0x61616100, - 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, - 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, - 0x53535300,0x18181800,0xf2f2f200,0x22222200, - 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, - 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, - 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, - 0x60606000,0xfcfcfc00,0x69696900,0x50505000, - 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, - 0xa1a1a100,0x89898900,0x62626200,0x97979700, - 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, - 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, - 0x10101000,0xc4c4c400,0x00000000,0x48484800, - 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, - 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, - 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, - 0x87878700,0x5c5c5c00,0x83838300,0x02020200, - 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, - 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, - 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, - 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, - 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, - 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, - 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, - 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, - 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, - 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, - 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, - 0x78787800,0x98989800,0x06060600,0x6a6a6a00, - 0xe7e7e700,0x46464600,0x71717100,0xbababa00, - 0xd4d4d400,0x25252500,0xababab00,0x42424200, - 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, - 0x72727200,0x07070700,0xb9b9b900,0x55555500, - 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, - 0x36363600,0x49494900,0x2a2a2a00,0x68686800, - 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, - 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, - 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, - 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, - 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, -}; - -static const u32 camellia_sp0222[256] = { - 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, - 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, - 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, - 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, - 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, - 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, - 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, - 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, - 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, - 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, - 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, - 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, - 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, - 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, - 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, - 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, - 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, - 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, - 0x00e8e8e8,0x00242424,0x00565656,0x00404040, - 0x00e1e1e1,0x00636363,0x00090909,0x00333333, - 0x00bfbfbf,0x00989898,0x00979797,0x00858585, - 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, - 0x00dadada,0x006f6f6f,0x00535353,0x00626262, - 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, - 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, - 0x00bdbdbd,0x00363636,0x00222222,0x00383838, - 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, - 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, - 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, - 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, - 0x00484848,0x00101010,0x00d1d1d1,0x00515151, - 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, - 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, - 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, - 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, - 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, - 0x00202020,0x00898989,0x00000000,0x00909090, - 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, - 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, - 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, - 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, - 0x009b9b9b,0x00949494,0x00212121,0x00666666, - 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, - 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, - 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, - 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, - 0x00030303,0x002d2d2d,0x00dedede,0x00969696, - 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, - 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, - 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, - 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, - 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, - 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, - 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, - 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, - 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, - 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, - 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, - 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, - 0x00787878,0x00707070,0x00e3e3e3,0x00494949, - 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, - 0x00777777,0x00939393,0x00868686,0x00838383, - 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, - 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, -}; - -static const u32 camellia_sp3033[256] = { - 0x38003838,0x41004141,0x16001616,0x76007676, - 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, - 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, - 0x75007575,0x06000606,0x57005757,0xa000a0a0, - 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, - 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, - 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, - 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, - 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, - 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, - 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, - 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, - 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, - 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, - 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, - 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, - 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, - 0xfd00fdfd,0x66006666,0x58005858,0x96009696, - 0x3a003a3a,0x09000909,0x95009595,0x10001010, - 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, - 0xef00efef,0x26002626,0xe500e5e5,0x61006161, - 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, - 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, - 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, - 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, - 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, - 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, - 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, - 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, - 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, - 0x12001212,0x04000404,0x74007474,0x54005454, - 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, - 0x55005555,0x68006868,0x50005050,0xbe00bebe, - 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, - 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, - 0x70007070,0xff00ffff,0x32003232,0x69006969, - 0x08000808,0x62006262,0x00000000,0x24002424, - 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, - 0x45004545,0x81008181,0x73007373,0x6d006d6d, - 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, - 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, - 0xe600e6e6,0x25002525,0x48004848,0x99009999, - 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, - 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, - 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, - 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, - 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, - 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, - 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, - 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, - 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, - 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, - 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, - 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, - 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, - 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, - 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, - 0x7c007c7c,0x77007777,0x56005656,0x05000505, - 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, - 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, - 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, - 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, - 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, - 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, -}; - -static const u32 camellia_sp4404[256] = { - 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, - 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, - 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, - 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, - 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, - 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, - 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, - 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, - 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, - 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, - 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, - 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, - 0x14140014,0x3a3a003a,0xdede00de,0x11110011, - 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, - 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, - 0x24240024,0xe8e800e8,0x60600060,0x69690069, - 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, - 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, - 0x10100010,0x00000000,0xa3a300a3,0x75750075, - 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, - 0x87870087,0x83830083,0xcdcd00cd,0x90900090, - 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, - 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, - 0x81810081,0x6f6f006f,0x13130013,0x63630063, - 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, - 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, - 0x78780078,0x06060006,0xe7e700e7,0x71710071, - 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, - 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, - 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, - 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, - 0x15150015,0xadad00ad,0x77770077,0x80800080, - 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, - 0x85850085,0x35350035,0x0c0c000c,0x41410041, - 0xefef00ef,0x93930093,0x19190019,0x21210021, - 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, - 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, - 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, - 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, - 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, - 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, - 0x12120012,0x20200020,0xb1b100b1,0x99990099, - 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, - 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, - 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, - 0x0f0f000f,0x16160016,0x18180018,0x22220022, - 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, - 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, - 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, - 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, - 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, - 0x03030003,0xdada00da,0x3f3f003f,0x94940094, - 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, - 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, - 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, - 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, - 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, - 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, - 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, - 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, - 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, - 0x49490049,0x68680068,0x38380038,0xa4a400a4, - 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, - 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, -}; - - - -static void camellia_setup128(const unsigned char *key, u32 *subkey) -{ - u32 kll, klr, krl, krr; - u32 il, ir, t0, t1, w0, w1; - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[26]; - u32 subR[26]; - - /** - * k == kll || klr || krl || krr (|| is concatination) - */ - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - /** - * generate KL dependent subkeys - */ - /* kw1 */ - SUBL(0) = kll; SUBR(0) = klr; - /* kw2 */ - SUBL(1) = krl; SUBR(1) = krr; - /* rotation left shift 15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k3 */ - SUBL(4) = kll; SUBR(4) = klr; - /* k4 */ - SUBL(5) = krl; SUBR(5) = krr; - /* rotation left shift 15+30bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k7 */ - SUBL(10) = kll; SUBR(10) = klr; - /* k8 */ - SUBL(11) = krl; SUBR(11) = krr; - /* rotation left shift 15+30+15bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k10 */ - SUBL(13) = krl; SUBR(13) = krr; - /* rotation left shift 15+30+15+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kl3 */ - SUBL(16) = kll; SUBR(16) = klr; - /* kl4 */ - SUBL(17) = krl; SUBR(17) = krr; - /* rotation left shift 15+30+15+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k13 */ - SUBL(18) = kll; SUBR(18) = klr; - /* k14 */ - SUBL(19) = krl; SUBR(19) = krr; - /* rotation left shift 15+30+15+17+17+17 bit */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - SUBL(22) = kll; SUBR(22) = klr; - /* k18 */ - SUBL(23) = krl; SUBR(23) = krr; - - /* generate KA */ - kll = SUBL(0); klr = SUBR(0); - krl = SUBL(1); krr = SUBR(1); - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - /* current status == (kll, klr, w0, w1) */ - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KA dependent subkeys */ - /* k1, k2 */ - SUBL(2) = kll; SUBR(2) = klr; - SUBL(3) = krl; SUBR(3) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5,k6 */ - SUBL(6) = kll; SUBR(6) = klr; - SUBL(7) = krl; SUBR(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl1, kl2 */ - SUBL(8) = kll; SUBR(8) = klr; - SUBL(9) = krl; SUBR(9) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k9 */ - SUBL(12) = kll; SUBR(12) = klr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k11, k12 */ - SUBL(14) = kll; SUBR(14) = klr; - SUBL(15) = krl; SUBR(15) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k15, k16 */ - SUBL(20) = kll; SUBR(20) = klr; - SUBL(21) = krl; SUBR(21) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* kw3, kw4 */ - SUBL(24) = kll; SUBR(24) = klr; - SUBL(25) = krl; SUBR(25) = krr; - - - /* absorb kw2 to other subkeys */ - /* round 2 */ - SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1); - /* round 4 */ - SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1); - /* round 6 */ - SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(9); - dw = SUBL(1) & SUBL(9), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ - /* round 8 */ - SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1); - /* round 10 */ - SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1); - /* round 12 */ - SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(17); - dw = SUBL(1) & SUBL(17), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ - /* round 14 */ - SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1); - /* round 16 */ - SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1); - /* round 18 */ - SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1); - /* kw3 */ - SUBL(24) ^= SUBL(1); SUBR(24) ^= SUBR(1); - - /* absorb kw4 to other subkeys */ - kw4l = SUBL(25); kw4r = SUBR(25); - /* round 17 */ - SUBL(22) ^= kw4l; SUBR(22) ^= kw4r; - /* round 15 */ - SUBL(20) ^= kw4l; SUBR(20) ^= kw4r; - /* round 13 */ - SUBL(18) ^= kw4l; SUBR(18) ^= kw4r; - kw4l ^= kw4r & ~SUBR(16); - dw = kw4l & SUBL(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ - /* round 11 */ - SUBL(14) ^= kw4l; SUBR(14) ^= kw4r; - /* round 9 */ - SUBL(12) ^= kw4l; SUBR(12) ^= kw4r; - /* round 7 */ - SUBL(10) ^= kw4l; SUBR(10) ^= kw4r; - kw4l ^= kw4r & ~SUBR(8); - dw = kw4l & SUBL(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ - /* round 5 */ - SUBL(6) ^= kw4l; SUBR(6) ^= kw4r; - /* round 3 */ - SUBL(4) ^= kw4l; SUBR(4) ^= kw4r; - /* round 1 */ - SUBL(2) ^= kw4l; SUBR(2) ^= kw4r; - /* kw1 */ - SUBL(0) ^= kw4l; SUBR(0) ^= kw4r; - - - /* key XOR is end of F-function */ - CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */ - CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2); - CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */ - CAMELLIA_SUBKEY_R(2) = SUBR(3); - CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */ - CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4); - CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */ - CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5); - CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */ - CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6); - CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */ - CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7); - tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8)); - dw = tl & SUBL(8), /* FL(kl1) */ - tr = SUBR(10) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */ - CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr; - CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */ - CAMELLIA_SUBKEY_R(8) = SUBR(8); - CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */ - CAMELLIA_SUBKEY_R(9) = SUBR(9); - tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9)); - dw = tl & SUBL(9), /* FLinv(kl2) */ - tr = SUBR(7) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */ - CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11); - CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */ - CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12); - CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */ - CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13); - CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */ - CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14); - CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */ - CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15); - tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16)); - dw = tl & SUBL(16), /* FL(kl3) */ - tr = SUBR(18) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */ - CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr; - CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */ - CAMELLIA_SUBKEY_R(16) = SUBR(16); - CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */ - CAMELLIA_SUBKEY_R(17) = SUBR(17); - tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17)); - dw = tl & SUBL(17), /* FLinv(kl4) */ - tr = SUBR(15) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */ - CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19); - CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */ - CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20); - CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */ - CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21); - CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */ - CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22); - CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */ - CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23); - CAMELLIA_SUBKEY_L(23) = SUBL(22); /* round 18 */ - CAMELLIA_SUBKEY_R(23) = SUBR(22); - CAMELLIA_SUBKEY_L(24) = SUBL(24) ^ SUBL(23); /* kw3 */ - CAMELLIA_SUBKEY_R(24) = SUBR(24) ^ SUBR(23); - - /* apply the inverse of the last half of P-function */ - dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw, - CAMELLIA_SUBKEY_L(2) = dw; - dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw, - CAMELLIA_SUBKEY_L(3) = dw; - dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw, - CAMELLIA_SUBKEY_L(4) = dw; - dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw, - CAMELLIA_SUBKEY_L(5) = dw; - dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw, - CAMELLIA_SUBKEY_L(6) = dw; - dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw, - CAMELLIA_SUBKEY_L(7) = dw; - dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw, - CAMELLIA_SUBKEY_L(10) = dw; - dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw, - CAMELLIA_SUBKEY_L(11) = dw; - dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw, - CAMELLIA_SUBKEY_L(12) = dw; - dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw, - CAMELLIA_SUBKEY_L(13) = dw; - dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw, - CAMELLIA_SUBKEY_L(14) = dw; - dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw, - CAMELLIA_SUBKEY_L(15) = dw; - dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw, - CAMELLIA_SUBKEY_L(18) = dw; - dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw, - CAMELLIA_SUBKEY_L(19) = dw; - dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw, - CAMELLIA_SUBKEY_L(20) = dw; - dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw, - CAMELLIA_SUBKEY_L(21) = dw; - dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw, - CAMELLIA_SUBKEY_L(22) = dw; - dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw, - CAMELLIA_SUBKEY_L(23) = dw; - - return; -} - - -static void camellia_setup256(const unsigned char *key, u32 *subkey) -{ - u32 kll,klr,krl,krr; /* left half of key */ - u32 krll,krlr,krrl,krrr; /* right half of key */ - u32 il, ir, t0, t1, w0, w1; /* temporary variables */ - u32 kw4l, kw4r, dw, tl, tr; - u32 subL[34]; - u32 subR[34]; - - /** - * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) - * (|| is concatination) - */ - - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - krll = GETU32(key + 16); - krlr = GETU32(key + 20); - krrl = GETU32(key + 24); - krrr = GETU32(key + 28); - - /* generate KL dependent subkeys */ - /* kw1 */ - SUBL(0) = kll; SUBR(0) = klr; - /* kw2 */ - SUBL(1) = krl; SUBR(1) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); - /* k9 */ - SUBL(12) = kll; SUBR(12) = klr; - /* k10 */ - SUBL(13) = krl; SUBR(13) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* kl3 */ - SUBL(16) = kll; SUBR(16) = klr; - /* kl4 */ - SUBL(17) = krl; SUBR(17) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - /* k17 */ - SUBL(22) = kll; SUBR(22) = klr; - /* k18 */ - SUBL(23) = krl; SUBR(23) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - /* k23 */ - SUBL(30) = kll; SUBR(30) = klr; - /* k24 */ - SUBL(31) = krl; SUBR(31) = krr; - - /* generate KR dependent subkeys */ - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* k3 */ - SUBL(4) = krll; SUBR(4) = krlr; - /* k4 */ - SUBL(5) = krrl; SUBR(5) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - /* kl1 */ - SUBL(8) = krll; SUBR(8) = krlr; - /* kl2 */ - SUBL(9) = krrl; SUBR(9) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k13 */ - SUBL(18) = krll; SUBR(18) = krlr; - /* k14 */ - SUBL(19) = krrl; SUBR(19) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - /* k19 */ - SUBL(26) = krll; SUBR(26) = krlr; - /* k20 */ - SUBL(27) = krrl; SUBR(27) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - - /* generate KA */ - kll = SUBL(0) ^ krll; klr = SUBR(0) ^ krlr; - krl = SUBL(1) ^ krrl; krr = SUBR(1) ^ krrr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - kll ^= krll; klr ^= krlr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KB */ - krll ^= kll; krlr ^= klr; - krrl ^= krl; krrr ^= krr; - CAMELLIA_F(krll, krlr, - CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, - w0, w1, il, ir, t0, t1); - krrl ^= w0; krrr ^= w1; - CAMELLIA_F(krrl, krrr, - CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, - w0, w1, il, ir, t0, t1); - krll ^= w0; krlr ^= w1; - - /* generate KA dependent subkeys */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - /* k5 */ - SUBL(6) = kll; SUBR(6) = klr; - /* k6 */ - SUBL(7) = krl; SUBR(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - /* k11 */ - SUBL(14) = kll; SUBR(14) = klr; - /* k12 */ - SUBL(15) = krl; SUBR(15) = krr; - /* rotation left shift 32bit */ - /* kl5 */ - SUBL(24) = klr; SUBR(24) = krl; - /* kl6 */ - SUBL(25) = krr; SUBR(25) = kll; - /* rotation left shift 49 from k11,k12 -> k21,k22 */ - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); - /* k21 */ - SUBL(28) = kll; SUBR(28) = klr; - /* k22 */ - SUBL(29) = krl; SUBR(29) = krr; - - /* generate KB dependent subkeys */ - /* k1 */ - SUBL(2) = krll; SUBR(2) = krlr; - /* k2 */ - SUBL(3) = krrl; SUBR(3) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k7 */ - SUBL(10) = krll; SUBR(10) = krlr; - /* k8 */ - SUBL(11) = krrl; SUBR(11) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - /* k15 */ - SUBL(20) = krll; SUBR(20) = krlr; - /* k16 */ - SUBL(21) = krrl; SUBR(21) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); - /* kw3 */ - SUBL(32) = krll; SUBR(32) = krlr; - /* kw4 */ - SUBL(33) = krrl; SUBR(33) = krrr; - - /* absorb kw2 to other subkeys */ - /* round 2 */ - SUBL(3) ^= SUBL(1); SUBR(3) ^= SUBR(1); - /* round 4 */ - SUBL(5) ^= SUBL(1); SUBR(5) ^= SUBR(1); - /* round 6 */ - SUBL(7) ^= SUBL(1); SUBR(7) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(9); - dw = SUBL(1) & SUBL(9), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ - /* round 8 */ - SUBL(11) ^= SUBL(1); SUBR(11) ^= SUBR(1); - /* round 10 */ - SUBL(13) ^= SUBL(1); SUBR(13) ^= SUBR(1); - /* round 12 */ - SUBL(15) ^= SUBL(1); SUBR(15) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(17); - dw = SUBL(1) & SUBL(17), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ - /* round 14 */ - SUBL(19) ^= SUBL(1); SUBR(19) ^= SUBR(1); - /* round 16 */ - SUBL(21) ^= SUBL(1); SUBR(21) ^= SUBR(1); - /* round 18 */ - SUBL(23) ^= SUBL(1); SUBR(23) ^= SUBR(1); - SUBL(1) ^= SUBR(1) & ~SUBR(25); - dw = SUBL(1) & SUBL(25), - SUBR(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */ - /* round 20 */ - SUBL(27) ^= SUBL(1); SUBR(27) ^= SUBR(1); - /* round 22 */ - SUBL(29) ^= SUBL(1); SUBR(29) ^= SUBR(1); - /* round 24 */ - SUBL(31) ^= SUBL(1); SUBR(31) ^= SUBR(1); - /* kw3 */ - SUBL(32) ^= SUBL(1); SUBR(32) ^= SUBR(1); - - - /* absorb kw4 to other subkeys */ - kw4l = SUBL(33); kw4r = SUBR(33); - /* round 23 */ - SUBL(30) ^= kw4l; SUBR(30) ^= kw4r; - /* round 21 */ - SUBL(28) ^= kw4l; SUBR(28) ^= kw4r; - /* round 19 */ - SUBL(26) ^= kw4l; SUBR(26) ^= kw4r; - kw4l ^= kw4r & ~SUBR(24); - dw = kw4l & SUBL(24), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */ - /* round 17 */ - SUBL(22) ^= kw4l; SUBR(22) ^= kw4r; - /* round 15 */ - SUBL(20) ^= kw4l; SUBR(20) ^= kw4r; - /* round 13 */ - SUBL(18) ^= kw4l; SUBR(18) ^= kw4r; - kw4l ^= kw4r & ~SUBR(16); - dw = kw4l & SUBL(16), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ - /* round 11 */ - SUBL(14) ^= kw4l; SUBR(14) ^= kw4r; - /* round 9 */ - SUBL(12) ^= kw4l; SUBR(12) ^= kw4r; - /* round 7 */ - SUBL(10) ^= kw4l; SUBR(10) ^= kw4r; - kw4l ^= kw4r & ~SUBR(8); - dw = kw4l & SUBL(8), - kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ - /* round 5 */ - SUBL(6) ^= kw4l; SUBR(6) ^= kw4r; - /* round 3 */ - SUBL(4) ^= kw4l; SUBR(4) ^= kw4r; - /* round 1 */ - SUBL(2) ^= kw4l; SUBR(2) ^= kw4r; - /* kw1 */ - SUBL(0) ^= kw4l; SUBR(0) ^= kw4r; - - /* key XOR is end of F-function */ - CAMELLIA_SUBKEY_L(0) = SUBL(0) ^ SUBL(2);/* kw1 */ - CAMELLIA_SUBKEY_R(0) = SUBR(0) ^ SUBR(2); - CAMELLIA_SUBKEY_L(2) = SUBL(3); /* round 1 */ - CAMELLIA_SUBKEY_R(2) = SUBR(3); - CAMELLIA_SUBKEY_L(3) = SUBL(2) ^ SUBL(4); /* round 2 */ - CAMELLIA_SUBKEY_R(3) = SUBR(2) ^ SUBR(4); - CAMELLIA_SUBKEY_L(4) = SUBL(3) ^ SUBL(5); /* round 3 */ - CAMELLIA_SUBKEY_R(4) = SUBR(3) ^ SUBR(5); - CAMELLIA_SUBKEY_L(5) = SUBL(4) ^ SUBL(6); /* round 4 */ - CAMELLIA_SUBKEY_R(5) = SUBR(4) ^ SUBR(6); - CAMELLIA_SUBKEY_L(6) = SUBL(5) ^ SUBL(7); /* round 5 */ - CAMELLIA_SUBKEY_R(6) = SUBR(5) ^ SUBR(7); - tl = SUBL(10) ^ (SUBR(10) & ~SUBR(8)); - dw = tl & SUBL(8), /* FL(kl1) */ - tr = SUBR(10) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(7) = SUBL(6) ^ tl; /* round 6 */ - CAMELLIA_SUBKEY_R(7) = SUBR(6) ^ tr; - CAMELLIA_SUBKEY_L(8) = SUBL(8); /* FL(kl1) */ - CAMELLIA_SUBKEY_R(8) = SUBR(8); - CAMELLIA_SUBKEY_L(9) = SUBL(9); /* FLinv(kl2) */ - CAMELLIA_SUBKEY_R(9) = SUBR(9); - tl = SUBL(7) ^ (SUBR(7) & ~SUBR(9)); - dw = tl & SUBL(9), /* FLinv(kl2) */ - tr = SUBR(7) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(10) = tl ^ SUBL(11); /* round 7 */ - CAMELLIA_SUBKEY_R(10) = tr ^ SUBR(11); - CAMELLIA_SUBKEY_L(11) = SUBL(10) ^ SUBL(12); /* round 8 */ - CAMELLIA_SUBKEY_R(11) = SUBR(10) ^ SUBR(12); - CAMELLIA_SUBKEY_L(12) = SUBL(11) ^ SUBL(13); /* round 9 */ - CAMELLIA_SUBKEY_R(12) = SUBR(11) ^ SUBR(13); - CAMELLIA_SUBKEY_L(13) = SUBL(12) ^ SUBL(14); /* round 10 */ - CAMELLIA_SUBKEY_R(13) = SUBR(12) ^ SUBR(14); - CAMELLIA_SUBKEY_L(14) = SUBL(13) ^ SUBL(15); /* round 11 */ - CAMELLIA_SUBKEY_R(14) = SUBR(13) ^ SUBR(15); - tl = SUBL(18) ^ (SUBR(18) & ~SUBR(16)); - dw = tl & SUBL(16), /* FL(kl3) */ - tr = SUBR(18) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(15) = SUBL(14) ^ tl; /* round 12 */ - CAMELLIA_SUBKEY_R(15) = SUBR(14) ^ tr; - CAMELLIA_SUBKEY_L(16) = SUBL(16); /* FL(kl3) */ - CAMELLIA_SUBKEY_R(16) = SUBR(16); - CAMELLIA_SUBKEY_L(17) = SUBL(17); /* FLinv(kl4) */ - CAMELLIA_SUBKEY_R(17) = SUBR(17); - tl = SUBL(15) ^ (SUBR(15) & ~SUBR(17)); - dw = tl & SUBL(17), /* FLinv(kl4) */ - tr = SUBR(15) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(18) = tl ^ SUBL(19); /* round 13 */ - CAMELLIA_SUBKEY_R(18) = tr ^ SUBR(19); - CAMELLIA_SUBKEY_L(19) = SUBL(18) ^ SUBL(20); /* round 14 */ - CAMELLIA_SUBKEY_R(19) = SUBR(18) ^ SUBR(20); - CAMELLIA_SUBKEY_L(20) = SUBL(19) ^ SUBL(21); /* round 15 */ - CAMELLIA_SUBKEY_R(20) = SUBR(19) ^ SUBR(21); - CAMELLIA_SUBKEY_L(21) = SUBL(20) ^ SUBL(22); /* round 16 */ - CAMELLIA_SUBKEY_R(21) = SUBR(20) ^ SUBR(22); - CAMELLIA_SUBKEY_L(22) = SUBL(21) ^ SUBL(23); /* round 17 */ - CAMELLIA_SUBKEY_R(22) = SUBR(21) ^ SUBR(23); - tl = SUBL(26) ^ (SUBR(26) - & ~SUBR(24)); - dw = tl & SUBL(24), /* FL(kl5) */ - tr = SUBR(26) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(23) = SUBL(22) ^ tl; /* round 18 */ - CAMELLIA_SUBKEY_R(23) = SUBR(22) ^ tr; - CAMELLIA_SUBKEY_L(24) = SUBL(24); /* FL(kl5) */ - CAMELLIA_SUBKEY_R(24) = SUBR(24); - CAMELLIA_SUBKEY_L(25) = SUBL(25); /* FLinv(kl6) */ - CAMELLIA_SUBKEY_R(25) = SUBR(25); - tl = SUBL(23) ^ (SUBR(23) & - ~SUBR(25)); - dw = tl & SUBL(25), /* FLinv(kl6) */ - tr = SUBR(23) ^ CAMELLIA_RL1(dw); - CAMELLIA_SUBKEY_L(26) = tl ^ SUBL(27); /* round 19 */ - CAMELLIA_SUBKEY_R(26) = tr ^ SUBR(27); - CAMELLIA_SUBKEY_L(27) = SUBL(26) ^ SUBL(28); /* round 20 */ - CAMELLIA_SUBKEY_R(27) = SUBR(26) ^ SUBR(28); - CAMELLIA_SUBKEY_L(28) = SUBL(27) ^ SUBL(29); /* round 21 */ - CAMELLIA_SUBKEY_R(28) = SUBR(27) ^ SUBR(29); - CAMELLIA_SUBKEY_L(29) = SUBL(28) ^ SUBL(30); /* round 22 */ - CAMELLIA_SUBKEY_R(29) = SUBR(28) ^ SUBR(30); - CAMELLIA_SUBKEY_L(30) = SUBL(29) ^ SUBL(31); /* round 23 */ - CAMELLIA_SUBKEY_R(30) = SUBR(29) ^ SUBR(31); - CAMELLIA_SUBKEY_L(31) = SUBL(30); /* round 24 */ - CAMELLIA_SUBKEY_R(31) = SUBR(30); - CAMELLIA_SUBKEY_L(32) = SUBL(32) ^ SUBL(31); /* kw3 */ - CAMELLIA_SUBKEY_R(32) = SUBR(32) ^ SUBR(31); - - /* apply the inverse of the last half of P-function */ - dw = CAMELLIA_SUBKEY_L(2) ^ CAMELLIA_SUBKEY_R(2), - dw = CAMELLIA_RL8(dw);/* round 1 */ - CAMELLIA_SUBKEY_R(2) = CAMELLIA_SUBKEY_L(2) ^ dw, - CAMELLIA_SUBKEY_L(2) = dw; - dw = CAMELLIA_SUBKEY_L(3) ^ CAMELLIA_SUBKEY_R(3), - dw = CAMELLIA_RL8(dw);/* round 2 */ - CAMELLIA_SUBKEY_R(3) = CAMELLIA_SUBKEY_L(3) ^ dw, - CAMELLIA_SUBKEY_L(3) = dw; - dw = CAMELLIA_SUBKEY_L(4) ^ CAMELLIA_SUBKEY_R(4), - dw = CAMELLIA_RL8(dw);/* round 3 */ - CAMELLIA_SUBKEY_R(4) = CAMELLIA_SUBKEY_L(4) ^ dw, - CAMELLIA_SUBKEY_L(4) = dw; - dw = CAMELLIA_SUBKEY_L(5) ^ CAMELLIA_SUBKEY_R(5), - dw = CAMELLIA_RL8(dw);/* round 4 */ - CAMELLIA_SUBKEY_R(5) = CAMELLIA_SUBKEY_L(5) ^ dw, - CAMELLIA_SUBKEY_L(5) = dw; - dw = CAMELLIA_SUBKEY_L(6) ^ CAMELLIA_SUBKEY_R(6), - dw = CAMELLIA_RL8(dw);/* round 5 */ - CAMELLIA_SUBKEY_R(6) = CAMELLIA_SUBKEY_L(6) ^ dw, - CAMELLIA_SUBKEY_L(6) = dw; - dw = CAMELLIA_SUBKEY_L(7) ^ CAMELLIA_SUBKEY_R(7), - dw = CAMELLIA_RL8(dw);/* round 6 */ - CAMELLIA_SUBKEY_R(7) = CAMELLIA_SUBKEY_L(7) ^ dw, - CAMELLIA_SUBKEY_L(7) = dw; - dw = CAMELLIA_SUBKEY_L(10) ^ CAMELLIA_SUBKEY_R(10), - dw = CAMELLIA_RL8(dw);/* round 7 */ - CAMELLIA_SUBKEY_R(10) = CAMELLIA_SUBKEY_L(10) ^ dw, - CAMELLIA_SUBKEY_L(10) = dw; - dw = CAMELLIA_SUBKEY_L(11) ^ CAMELLIA_SUBKEY_R(11), - dw = CAMELLIA_RL8(dw);/* round 8 */ - CAMELLIA_SUBKEY_R(11) = CAMELLIA_SUBKEY_L(11) ^ dw, - CAMELLIA_SUBKEY_L(11) = dw; - dw = CAMELLIA_SUBKEY_L(12) ^ CAMELLIA_SUBKEY_R(12), - dw = CAMELLIA_RL8(dw);/* round 9 */ - CAMELLIA_SUBKEY_R(12) = CAMELLIA_SUBKEY_L(12) ^ dw, - CAMELLIA_SUBKEY_L(12) = dw; - dw = CAMELLIA_SUBKEY_L(13) ^ CAMELLIA_SUBKEY_R(13), - dw = CAMELLIA_RL8(dw);/* round 10 */ - CAMELLIA_SUBKEY_R(13) = CAMELLIA_SUBKEY_L(13) ^ dw, - CAMELLIA_SUBKEY_L(13) = dw; - dw = CAMELLIA_SUBKEY_L(14) ^ CAMELLIA_SUBKEY_R(14), - dw = CAMELLIA_RL8(dw);/* round 11 */ - CAMELLIA_SUBKEY_R(14) = CAMELLIA_SUBKEY_L(14) ^ dw, - CAMELLIA_SUBKEY_L(14) = dw; - dw = CAMELLIA_SUBKEY_L(15) ^ CAMELLIA_SUBKEY_R(15), - dw = CAMELLIA_RL8(dw);/* round 12 */ - CAMELLIA_SUBKEY_R(15) = CAMELLIA_SUBKEY_L(15) ^ dw, - CAMELLIA_SUBKEY_L(15) = dw; - dw = CAMELLIA_SUBKEY_L(18) ^ CAMELLIA_SUBKEY_R(18), - dw = CAMELLIA_RL8(dw);/* round 13 */ - CAMELLIA_SUBKEY_R(18) = CAMELLIA_SUBKEY_L(18) ^ dw, - CAMELLIA_SUBKEY_L(18) = dw; - dw = CAMELLIA_SUBKEY_L(19) ^ CAMELLIA_SUBKEY_R(19), - dw = CAMELLIA_RL8(dw);/* round 14 */ - CAMELLIA_SUBKEY_R(19) = CAMELLIA_SUBKEY_L(19) ^ dw, - CAMELLIA_SUBKEY_L(19) = dw; - dw = CAMELLIA_SUBKEY_L(20) ^ CAMELLIA_SUBKEY_R(20), - dw = CAMELLIA_RL8(dw);/* round 15 */ - CAMELLIA_SUBKEY_R(20) = CAMELLIA_SUBKEY_L(20) ^ dw, - CAMELLIA_SUBKEY_L(20) = dw; - dw = CAMELLIA_SUBKEY_L(21) ^ CAMELLIA_SUBKEY_R(21), - dw = CAMELLIA_RL8(dw);/* round 16 */ - CAMELLIA_SUBKEY_R(21) = CAMELLIA_SUBKEY_L(21) ^ dw, - CAMELLIA_SUBKEY_L(21) = dw; - dw = CAMELLIA_SUBKEY_L(22) ^ CAMELLIA_SUBKEY_R(22), - dw = CAMELLIA_RL8(dw);/* round 17 */ - CAMELLIA_SUBKEY_R(22) = CAMELLIA_SUBKEY_L(22) ^ dw, - CAMELLIA_SUBKEY_L(22) = dw; - dw = CAMELLIA_SUBKEY_L(23) ^ CAMELLIA_SUBKEY_R(23), - dw = CAMELLIA_RL8(dw);/* round 18 */ - CAMELLIA_SUBKEY_R(23) = CAMELLIA_SUBKEY_L(23) ^ dw, - CAMELLIA_SUBKEY_L(23) = dw; - dw = CAMELLIA_SUBKEY_L(26) ^ CAMELLIA_SUBKEY_R(26), - dw = CAMELLIA_RL8(dw);/* round 19 */ - CAMELLIA_SUBKEY_R(26) = CAMELLIA_SUBKEY_L(26) ^ dw, - CAMELLIA_SUBKEY_L(26) = dw; - dw = CAMELLIA_SUBKEY_L(27) ^ CAMELLIA_SUBKEY_R(27), - dw = CAMELLIA_RL8(dw);/* round 20 */ - CAMELLIA_SUBKEY_R(27) = CAMELLIA_SUBKEY_L(27) ^ dw, - CAMELLIA_SUBKEY_L(27) = dw; - dw = CAMELLIA_SUBKEY_L(28) ^ CAMELLIA_SUBKEY_R(28), - dw = CAMELLIA_RL8(dw);/* round 21 */ - CAMELLIA_SUBKEY_R(28) = CAMELLIA_SUBKEY_L(28) ^ dw, - CAMELLIA_SUBKEY_L(28) = dw; - dw = CAMELLIA_SUBKEY_L(29) ^ CAMELLIA_SUBKEY_R(29), - dw = CAMELLIA_RL8(dw);/* round 22 */ - CAMELLIA_SUBKEY_R(29) = CAMELLIA_SUBKEY_L(29) ^ dw, - CAMELLIA_SUBKEY_L(29) = dw; - dw = CAMELLIA_SUBKEY_L(30) ^ CAMELLIA_SUBKEY_R(30), - dw = CAMELLIA_RL8(dw);/* round 23 */ - CAMELLIA_SUBKEY_R(30) = CAMELLIA_SUBKEY_L(30) ^ dw, - CAMELLIA_SUBKEY_L(30) = dw; - dw = CAMELLIA_SUBKEY_L(31) ^ CAMELLIA_SUBKEY_R(31), - dw = CAMELLIA_RL8(dw);/* round 24 */ - CAMELLIA_SUBKEY_R(31) = CAMELLIA_SUBKEY_L(31) ^ dw, - CAMELLIA_SUBKEY_L(31) = dw; - - return; -} - -static void camellia_setup192(const unsigned char *key, u32 *subkey) -{ - unsigned char kk[32]; - u32 krll, krlr, krrl,krrr; - - memcpy(kk, key, 24); - memcpy((unsigned char *)&krll, key+16,4); - memcpy((unsigned char *)&krlr, key+20,4); - krrl = ~krll; - krrr = ~krlr; - memcpy(kk+24, (unsigned char *)&krrl, 4); - memcpy(kk+28, (unsigned char *)&krrr, 4); - camellia_setup256(kk, subkey); - return; -} - - -/** - * Stuff related to camellia encryption/decryption - */ -static void camellia_encrypt128(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(0); - io[1] ^= CAMELLIA_SUBKEY_R(0); - /* main iteration */ - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(24); - io[3] ^= CAMELLIA_SUBKEY_R(24); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - -static void camellia_decrypt128(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(24); - io[1] ^= CAMELLIA_SUBKEY_R(24); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(0); - io[3] ^= CAMELLIA_SUBKEY_R(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -/** - * stuff for 192 and 256bit encryption/decryption - */ -static void camellia_encrypt256(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(0); - io[1] ^= CAMELLIA_SUBKEY_R(0); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24), - CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(32); - io[3] ^= CAMELLIA_SUBKEY_R(32); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -static void camellia_decrypt256(const u32 *subkey, __be32 *io_text) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - u32 io[4]; - - io[0] = be32_to_cpu(io_text[0]); - io[1] = be32_to_cpu(io_text[1]); - io[2] = be32_to_cpu(io_text[2]); - io[3] = be32_to_cpu(io_text[3]); - - /* pre whitening but absorb kw2*/ - io[0] ^= CAMELLIA_SUBKEY_L(32); - io[1] ^= CAMELLIA_SUBKEY_R(32); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(31),CAMELLIA_SUBKEY_R(31), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(30),CAMELLIA_SUBKEY_R(30), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(29),CAMELLIA_SUBKEY_R(29), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(28),CAMELLIA_SUBKEY_R(28), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(27),CAMELLIA_SUBKEY_R(27), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(26),CAMELLIA_SUBKEY_R(26), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(25),CAMELLIA_SUBKEY_R(25), - CAMELLIA_SUBKEY_L(24),CAMELLIA_SUBKEY_R(24), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(23),CAMELLIA_SUBKEY_R(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(22),CAMELLIA_SUBKEY_R(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(21),CAMELLIA_SUBKEY_R(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(20),CAMELLIA_SUBKEY_R(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(19),CAMELLIA_SUBKEY_R(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(18),CAMELLIA_SUBKEY_R(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(17),CAMELLIA_SUBKEY_R(17), - CAMELLIA_SUBKEY_L(16),CAMELLIA_SUBKEY_R(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(15),CAMELLIA_SUBKEY_R(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(14),CAMELLIA_SUBKEY_R(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(13),CAMELLIA_SUBKEY_R(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(12),CAMELLIA_SUBKEY_R(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(11),CAMELLIA_SUBKEY_R(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(10),CAMELLIA_SUBKEY_R(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CAMELLIA_SUBKEY_L(9),CAMELLIA_SUBKEY_R(9), - CAMELLIA_SUBKEY_L(8),CAMELLIA_SUBKEY_R(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(7),CAMELLIA_SUBKEY_R(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(6),CAMELLIA_SUBKEY_R(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(5),CAMELLIA_SUBKEY_R(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(4),CAMELLIA_SUBKEY_R(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CAMELLIA_SUBKEY_L(3),CAMELLIA_SUBKEY_R(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CAMELLIA_SUBKEY_L(2),CAMELLIA_SUBKEY_R(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CAMELLIA_SUBKEY_L(0); - io[3] ^= CAMELLIA_SUBKEY_R(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - io_text[0] = cpu_to_be32(io[0]); - io_text[1] = cpu_to_be32(io[1]); - io_text[2] = cpu_to_be32(io[2]); - io_text[3] = cpu_to_be32(io[3]); - - return; -} - - -static int -camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key, - unsigned int key_len) -{ - struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const unsigned char *key = (const unsigned char *)in_key; - u32 *flags = &tfm->crt_flags; - - if (key_len != 16 && key_len != 24 && key_len != 32) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; - } - - cctx->key_length = key_len; - - switch(key_len) { - case 16: - camellia_setup128(key, cctx->key_table); - break; - case 24: - camellia_setup192(key, cctx->key_table); - break; - case 32: - camellia_setup256(key, cctx->key_table); - break; - default: - break; - } - - return 0; -} - - -static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) -{ - const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const __be32 *src = (const __be32 *)in; - __be32 *dst = (__be32 *)out; - - __be32 tmp[4]; - - memcpy(tmp, src, CAMELLIA_BLOCK_SIZE); - - switch (cctx->key_length) { - case 16: - camellia_encrypt128(cctx->key_table, tmp); - break; - case 24: - /* fall through */ - case 32: - camellia_encrypt256(cctx->key_table, tmp); - break; - default: - break; - } - - memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE); -} - - -static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) -{ - const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); - const __be32 *src = (const __be32 *)in; - __be32 *dst = (__be32 *)out; - - __be32 tmp[4]; - - memcpy(tmp, src, CAMELLIA_BLOCK_SIZE); - - switch (cctx->key_length) { - case 16: - camellia_decrypt128(cctx->key_table, tmp); - break; - case 24: - /* fall through */ - case 32: - camellia_decrypt256(cctx->key_table, tmp); - break; - default: - break; - } - - memcpy(dst, tmp, CAMELLIA_BLOCK_SIZE); -} - - -static struct crypto_alg camellia_alg = { - .cra_name = "camellia", - .cra_driver_name = "camellia-generic", - .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, - .cra_blocksize = CAMELLIA_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct camellia_ctx), - .cra_alignmask = 3, - .cra_module = THIS_MODULE, - .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list), - .cra_u = { - .cipher = { - .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE, - .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE, - .cia_setkey = camellia_set_key, - .cia_encrypt = camellia_encrypt, - .cia_decrypt = camellia_decrypt - } - } -}; - -static int __init camellia_init(void) -{ - return crypto_register_alg(&camellia_alg); -} - - -static void __exit camellia_fini(void) -{ - crypto_unregister_alg(&camellia_alg); -} - - -module_init(camellia_init); -module_exit(camellia_fini); - - -MODULE_DESCRIPTION("Camellia Cipher Algorithm"); -MODULE_LICENSE("GPL"); diff --git a/trunk/crypto/cbc.c b/trunk/crypto/cbc.c index 136fea7e7000..f5542b4db387 100644 --- a/trunk/crypto/cbc.c +++ b/trunk/crypto/cbc.c @@ -243,7 +243,6 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm) struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_cbc_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -261,11 +260,11 @@ static int crypto_cbc_init_tfm(struct crypto_tfm *tfm) ctx->xor = xor_quad; } - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/cipher.c b/trunk/crypto/cipher.c index 333aab2f0277..9e03701cfdcc 100644 --- a/trunk/crypto/cipher.c +++ b/trunk/crypto/cipher.c @@ -12,13 +12,274 @@ * any later version. * */ - +#include #include #include #include -#include +#include +#include #include +#include #include "internal.h" +#include "scatterwalk.h" + +struct cipher_alg_compat { + unsigned int cia_min_keysize; + unsigned int cia_max_keysize; + int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key, + unsigned int keylen); + void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); + void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); + + unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); +}; + +static inline void xor_64(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; +} + +static inline void xor_128(u8 *a, const u8 *b) +{ + ((u32 *)a)[0] ^= ((u32 *)b)[0]; + ((u32 *)a)[1] ^= ((u32 *)b)[1]; + ((u32 *)a)[2] ^= ((u32 *)b)[2]; + ((u32 *)a)[3] ^= ((u32 *)b)[3]; +} + +static unsigned int crypt_slow(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, unsigned int bsize) +{ + unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm); + u8 buffer[bsize * 2 + alignmask]; + u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + u8 *dst = src + bsize; + + scatterwalk_copychunks(src, in, bsize, 0); + desc->prfn(desc, dst, src, bsize); + scatterwalk_copychunks(dst, out, bsize, 1); + + return bsize; +} + +static inline unsigned int crypt_fast(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, + unsigned int nbytes, u8 *tmp) +{ + u8 *src, *dst; + u8 *real_src, *real_dst; + + real_src = scatterwalk_map(in, 0); + real_dst = scatterwalk_map(out, 1); + + src = real_src; + dst = scatterwalk_samebuf(in, out) ? src : real_dst; + + if (tmp) { + memcpy(tmp, src, nbytes); + src = tmp; + dst = tmp; + } + + nbytes = desc->prfn(desc, dst, src, nbytes); + + if (tmp) + memcpy(real_dst, tmp, nbytes); + + scatterwalk_unmap(real_src, 0); + scatterwalk_unmap(real_dst, 1); + + scatterwalk_advance(in, nbytes); + scatterwalk_advance(out, nbytes); + + return nbytes; +} + +/* + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per page. + */ +static int crypt(const struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct scatter_walk walk_in, walk_out; + struct crypto_tfm *tfm = desc->tfm; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); + unsigned long buffer = 0; + + if (!nbytes) + return 0; + + if (nbytes % bsize) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; + return -EINVAL; + } + + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + unsigned int n = nbytes; + u8 *tmp = NULL; + + if (!scatterwalk_aligned(&walk_in, alignmask) || + !scatterwalk_aligned(&walk_out, alignmask)) { + if (!buffer) { + buffer = __get_free_page(GFP_ATOMIC); + if (!buffer) + n = 0; + } + tmp = (u8 *)buffer; + } + + n = scatterwalk_clamp(&walk_in, n); + n = scatterwalk_clamp(&walk_out, n); + + if (likely(n >= bsize)) + n = crypt_fast(desc, &walk_in, &walk_out, n, tmp); + else + n = crypt_slow(desc, &walk_in, &walk_out, bsize); + + nbytes -= n; + + scatterwalk_done(&walk_in, 0, nbytes); + scatterwalk_done(&walk_out, 1, nbytes); + + if (!nbytes) + break; + + crypto_yield(tfm->crt_flags); + } + + if (buffer) + free_page(buffer); + + return 0; +} + +static int crypt_iv_unaligned(struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); + u8 *iv = desc->info; + + if (unlikely(((unsigned long)iv & alignmask))) { + unsigned int ivsize = tfm->crt_cipher.cit_ivsize; + u8 buffer[ivsize + alignmask]; + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + int err; + + desc->info = memcpy(tmp, iv, ivsize); + err = crypt(desc, dst, src, nbytes); + memcpy(iv, tmp, ivsize); + + return err; + } + + return crypt(desc, dst, src, nbytes); +} + +static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + nbytes -= bsize; + + do { + xor(iv, src); + fn(tfm, dst, iv); + memcpy(iv, dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} + +static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm); + + u8 stack[src == dst ? bsize + alignmask : 0]; + u8 *buf = (u8 *)ALIGN((unsigned long)stack, alignmask + 1); + u8 **dst_p = src == dst ? &buf : &dst; + + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + nbytes -= bsize; + + do { + u8 *tmp_dst = *dst_p; + + fn(tfm, tmp_dst, src); + xor(tmp_dst, iv); + memcpy(iv, src, bsize); + if (tmp_dst != dst) + memcpy(dst, tmp_dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} + +static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + int bsize = crypto_tfm_alg_blocksize(tfm); + void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = desc->crfn; + unsigned int done = 0; + + nbytes -= bsize; + + do { + fn(tfm, dst, src); + + src += bsize; + dst += bsize; + } while ((done += bsize) <= nbytes); + + return done; +} static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { @@ -32,6 +293,122 @@ static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) return cia->cia_setkey(tfm, key, keylen); } +static int ecb_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); +} + +static int ecb_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); +} + +static int cbc_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); +} + +static int cbc_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + struct cipher_desc desc; + struct cipher_alg_compat *cipher = (void *)&tfm->__crt_alg->cra_cipher; + + desc.tfm = tfm; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; + desc.info = iv; + + return crypt_iv_unaligned(&desc, dst, src, nbytes); +} + +static int nocrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + return -ENOSYS; +} + +static int nocrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + return -ENOSYS; +} + +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) +{ + u32 mode = flags & CRYPTO_TFM_MODE_MASK; + tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; + return 0; +} + static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, const u8 *), struct crypto_tfm *tfm, @@ -77,6 +454,7 @@ static void cipher_decrypt_unaligned(struct crypto_tfm *tfm, int crypto_init_cipher_ops(struct crypto_tfm *tfm) { + int ret = 0; struct cipher_tfm *ops = &tfm->crt_cipher; struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; @@ -86,7 +464,70 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) ops->cit_decrypt_one = crypto_tfm_alg_alignmask(tfm) ? cipher_decrypt_unaligned : cipher->cia_decrypt; - return 0; + switch (tfm->crt_cipher.cit_mode) { + case CRYPTO_TFM_MODE_ECB: + ops->cit_encrypt = ecb_encrypt; + ops->cit_decrypt = ecb_decrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CBC: + ops->cit_encrypt = cbc_encrypt; + ops->cit_decrypt = cbc_decrypt; + ops->cit_encrypt_iv = cbc_encrypt_iv; + ops->cit_decrypt_iv = cbc_decrypt_iv; + break; + + case CRYPTO_TFM_MODE_CFB: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + case CRYPTO_TFM_MODE_CTR: + ops->cit_encrypt = nocrypt; + ops->cit_decrypt = nocrypt; + ops->cit_encrypt_iv = nocrypt_iv; + ops->cit_decrypt_iv = nocrypt_iv; + break; + + default: + BUG(); + } + + if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { + unsigned long align; + unsigned long addr; + + switch (crypto_tfm_alg_blocksize(tfm)) { + case 8: + ops->cit_xor_block = xor_64; + break; + + case 16: + ops->cit_xor_block = xor_128; + break; + + default: + printk(KERN_WARNING "%s: block size %u not supported\n", + crypto_tfm_alg_name(tfm), + crypto_tfm_alg_blocksize(tfm)); + ret = -EINVAL; + goto out; + } + + ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); + align = crypto_tfm_alg_alignmask(tfm) + 1; + addr = (unsigned long)crypto_tfm_ctx(tfm); + addr = ALIGN(addr, align); + addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align); + ops->cit_iv = (void *)addr; + } + +out: + return ret; } void crypto_exit_cipher_ops(struct crypto_tfm *tfm) diff --git a/trunk/crypto/compress.c b/trunk/crypto/compress.c index 0a6570048c1e..eca182aa3380 100644 --- a/trunk/crypto/compress.c +++ b/trunk/crypto/compress.c @@ -34,6 +34,11 @@ static int crypto_decompress(struct crypto_tfm *tfm, dlen); } +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + int crypto_init_compress_ops(struct crypto_tfm *tfm) { struct compress_tfm *ops = &tfm->crt_compress; diff --git a/trunk/crypto/digest.c b/trunk/crypto/digest.c index 1bf7414aeb9e..8f4593268ce0 100644 --- a/trunk/crypto/digest.c +++ b/trunk/crypto/digest.c @@ -14,9 +14,7 @@ #include #include -#include #include -#include #include #include @@ -31,8 +29,8 @@ static int init(struct hash_desc *desc) return 0; } -static int update2(struct hash_desc *desc, - struct scatterlist *sg, unsigned int nbytes) +static int update(struct hash_desc *desc, + struct scatterlist *sg, unsigned int nbytes) { struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); @@ -83,14 +81,6 @@ static int update2(struct hash_desc *desc, return 0; } -static int update(struct hash_desc *desc, - struct scatterlist *sg, unsigned int nbytes) -{ - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - return update2(desc, sg, nbytes); -} - static int final(struct hash_desc *desc, u8 *out) { struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); @@ -128,14 +118,16 @@ static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen) static int digest(struct hash_desc *desc, struct scatterlist *sg, unsigned int nbytes, u8 *out) { - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - init(desc); - update2(desc, sg, nbytes); + update(desc, sg, nbytes); return final(desc, out); } +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) +{ + return flags ? -EINVAL : 0; +} + int crypto_init_digest_ops(struct crypto_tfm *tfm) { struct hash_tfm *ops = &tfm->crt_hash; diff --git a/trunk/crypto/ecb.c b/trunk/crypto/ecb.c index 839a0aed8c22..f239aa9c4017 100644 --- a/trunk/crypto/ecb.c +++ b/trunk/crypto/ecb.c @@ -99,13 +99,12 @@ static int crypto_ecb_init_tfm(struct crypto_tfm *tfm) struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/fcrypt.c b/trunk/crypto/fcrypt.c deleted file mode 100644 index 9c2bb535b09a..000000000000 --- a/trunk/crypto/fcrypt.c +++ /dev/null @@ -1,423 +0,0 @@ -/* FCrypt encryption algorithm - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.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. - * - * Based on code: - * - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#define ROUNDS 16 - -struct fcrypt_ctx { - u32 sched[ROUNDS]; -}; - -/* Rotate right two 32 bit numbers as a 56 bit number */ -#define ror56(hi, lo, n) \ -do { \ - u32 t = lo & ((1 << n) - 1); \ - lo = (lo >> n) | ((hi & ((1 << n) - 1)) << (32 - n)); \ - hi = (hi >> n) | (t << (24-n)); \ -} while(0) - -/* Rotate right one 64 bit number as a 56 bit number */ -#define ror56_64(k, n) \ -do { \ - k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)); \ -} while(0) - -/* - * Sboxes for Feistel network derived from - * /afs/transarc.com/public/afsps/afs.rel31b.export-src/rxkad/sboxes.h - */ -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 3) -static const u32 sbox0[256] = { - Z(0xea), Z(0x7f), Z(0xb2), Z(0x64), Z(0x9d), Z(0xb0), Z(0xd9), Z(0x11), - Z(0xcd), Z(0x86), Z(0x86), Z(0x91), Z(0x0a), Z(0xb2), Z(0x93), Z(0x06), - Z(0x0e), Z(0x06), Z(0xd2), Z(0x65), Z(0x73), Z(0xc5), Z(0x28), Z(0x60), - Z(0xf2), Z(0x20), Z(0xb5), Z(0x38), Z(0x7e), Z(0xda), Z(0x9f), Z(0xe3), - Z(0xd2), Z(0xcf), Z(0xc4), Z(0x3c), Z(0x61), Z(0xff), Z(0x4a), Z(0x4a), - Z(0x35), Z(0xac), Z(0xaa), Z(0x5f), Z(0x2b), Z(0xbb), Z(0xbc), Z(0x53), - Z(0x4e), Z(0x9d), Z(0x78), Z(0xa3), Z(0xdc), Z(0x09), Z(0x32), Z(0x10), - Z(0xc6), Z(0x6f), Z(0x66), Z(0xd6), Z(0xab), Z(0xa9), Z(0xaf), Z(0xfd), - Z(0x3b), Z(0x95), Z(0xe8), Z(0x34), Z(0x9a), Z(0x81), Z(0x72), Z(0x80), - Z(0x9c), Z(0xf3), Z(0xec), Z(0xda), Z(0x9f), Z(0x26), Z(0x76), Z(0x15), - Z(0x3e), Z(0x55), Z(0x4d), Z(0xde), Z(0x84), Z(0xee), Z(0xad), Z(0xc7), - Z(0xf1), Z(0x6b), Z(0x3d), Z(0xd3), Z(0x04), Z(0x49), Z(0xaa), Z(0x24), - Z(0x0b), Z(0x8a), Z(0x83), Z(0xba), Z(0xfa), Z(0x85), Z(0xa0), Z(0xa8), - Z(0xb1), Z(0xd4), Z(0x01), Z(0xd8), Z(0x70), Z(0x64), Z(0xf0), Z(0x51), - Z(0xd2), Z(0xc3), Z(0xa7), Z(0x75), Z(0x8c), Z(0xa5), Z(0x64), Z(0xef), - Z(0x10), Z(0x4e), Z(0xb7), Z(0xc6), Z(0x61), Z(0x03), Z(0xeb), Z(0x44), - Z(0x3d), Z(0xe5), Z(0xb3), Z(0x5b), Z(0xae), Z(0xd5), Z(0xad), Z(0x1d), - Z(0xfa), Z(0x5a), Z(0x1e), Z(0x33), Z(0xab), Z(0x93), Z(0xa2), Z(0xb7), - Z(0xe7), Z(0xa8), Z(0x45), Z(0xa4), Z(0xcd), Z(0x29), Z(0x63), Z(0x44), - Z(0xb6), Z(0x69), Z(0x7e), Z(0x2e), Z(0x62), Z(0x03), Z(0xc8), Z(0xe0), - Z(0x17), Z(0xbb), Z(0xc7), Z(0xf3), Z(0x3f), Z(0x36), Z(0xba), Z(0x71), - Z(0x8e), Z(0x97), Z(0x65), Z(0x60), Z(0x69), Z(0xb6), Z(0xf6), Z(0xe6), - Z(0x6e), Z(0xe0), Z(0x81), Z(0x59), Z(0xe8), Z(0xaf), Z(0xdd), Z(0x95), - Z(0x22), Z(0x99), Z(0xfd), Z(0x63), Z(0x19), Z(0x74), Z(0x61), Z(0xb1), - Z(0xb6), Z(0x5b), Z(0xae), Z(0x54), Z(0xb3), Z(0x70), Z(0xff), Z(0xc6), - Z(0x3b), Z(0x3e), Z(0xc1), Z(0xd7), Z(0xe1), Z(0x0e), Z(0x76), Z(0xe5), - Z(0x36), Z(0x4f), Z(0x59), Z(0xc7), Z(0x08), Z(0x6e), Z(0x82), Z(0xa6), - Z(0x93), Z(0xc4), Z(0xaa), Z(0x26), Z(0x49), Z(0xe0), Z(0x21), Z(0x64), - Z(0x07), Z(0x9f), Z(0x64), Z(0x81), Z(0x9c), Z(0xbf), Z(0xf9), Z(0xd1), - Z(0x43), Z(0xf8), Z(0xb6), Z(0xb9), Z(0xf1), Z(0x24), Z(0x75), Z(0x03), - Z(0xe4), Z(0xb0), Z(0x99), Z(0x46), Z(0x3d), Z(0xf5), Z(0xd1), Z(0x39), - Z(0x72), Z(0x12), Z(0xf6), Z(0xba), Z(0x0c), Z(0x0d), Z(0x42), Z(0x2e) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu((x << 27) | (x >> 5)) -static const u32 sbox1[256] = { - Z(0x77), Z(0x14), Z(0xa6), Z(0xfe), Z(0xb2), Z(0x5e), Z(0x8c), Z(0x3e), - Z(0x67), Z(0x6c), Z(0xa1), Z(0x0d), Z(0xc2), Z(0xa2), Z(0xc1), Z(0x85), - Z(0x6c), Z(0x7b), Z(0x67), Z(0xc6), Z(0x23), Z(0xe3), Z(0xf2), Z(0x89), - Z(0x50), Z(0x9c), Z(0x03), Z(0xb7), Z(0x73), Z(0xe6), Z(0xe1), Z(0x39), - Z(0x31), Z(0x2c), Z(0x27), Z(0x9f), Z(0xa5), Z(0x69), Z(0x44), Z(0xd6), - Z(0x23), Z(0x83), Z(0x98), Z(0x7d), Z(0x3c), Z(0xb4), Z(0x2d), Z(0x99), - Z(0x1c), Z(0x1f), Z(0x8c), Z(0x20), Z(0x03), Z(0x7c), Z(0x5f), Z(0xad), - Z(0xf4), Z(0xfa), Z(0x95), Z(0xca), Z(0x76), Z(0x44), Z(0xcd), Z(0xb6), - Z(0xb8), Z(0xa1), Z(0xa1), Z(0xbe), Z(0x9e), Z(0x54), Z(0x8f), Z(0x0b), - Z(0x16), Z(0x74), Z(0x31), Z(0x8a), Z(0x23), Z(0x17), Z(0x04), Z(0xfa), - Z(0x79), Z(0x84), Z(0xb1), Z(0xf5), Z(0x13), Z(0xab), Z(0xb5), Z(0x2e), - Z(0xaa), Z(0x0c), Z(0x60), Z(0x6b), Z(0x5b), Z(0xc4), Z(0x4b), Z(0xbc), - Z(0xe2), Z(0xaf), Z(0x45), Z(0x73), Z(0xfa), Z(0xc9), Z(0x49), Z(0xcd), - Z(0x00), Z(0x92), Z(0x7d), Z(0x97), Z(0x7a), Z(0x18), Z(0x60), Z(0x3d), - Z(0xcf), Z(0x5b), Z(0xde), Z(0xc6), Z(0xe2), Z(0xe6), Z(0xbb), Z(0x8b), - Z(0x06), Z(0xda), Z(0x08), Z(0x15), Z(0x1b), Z(0x88), Z(0x6a), Z(0x17), - Z(0x89), Z(0xd0), Z(0xa9), Z(0xc1), Z(0xc9), Z(0x70), Z(0x6b), Z(0xe5), - Z(0x43), Z(0xf4), Z(0x68), Z(0xc8), Z(0xd3), Z(0x84), Z(0x28), Z(0x0a), - Z(0x52), Z(0x66), Z(0xa3), Z(0xca), Z(0xf2), Z(0xe3), Z(0x7f), Z(0x7a), - Z(0x31), Z(0xf7), Z(0x88), Z(0x94), Z(0x5e), Z(0x9c), Z(0x63), Z(0xd5), - Z(0x24), Z(0x66), Z(0xfc), Z(0xb3), Z(0x57), Z(0x25), Z(0xbe), Z(0x89), - Z(0x44), Z(0xc4), Z(0xe0), Z(0x8f), Z(0x23), Z(0x3c), Z(0x12), Z(0x52), - Z(0xf5), Z(0x1e), Z(0xf4), Z(0xcb), Z(0x18), Z(0x33), Z(0x1f), Z(0xf8), - Z(0x69), Z(0x10), Z(0x9d), Z(0xd3), Z(0xf7), Z(0x28), Z(0xf8), Z(0x30), - Z(0x05), Z(0x5e), Z(0x32), Z(0xc0), Z(0xd5), Z(0x19), Z(0xbd), Z(0x45), - Z(0x8b), Z(0x5b), Z(0xfd), Z(0xbc), Z(0xe2), Z(0x5c), Z(0xa9), Z(0x96), - Z(0xef), Z(0x70), Z(0xcf), Z(0xc2), Z(0x2a), Z(0xb3), Z(0x61), Z(0xad), - Z(0x80), Z(0x48), Z(0x81), Z(0xb7), Z(0x1d), Z(0x43), Z(0xd9), Z(0xd7), - Z(0x45), Z(0xf0), Z(0xd8), Z(0x8a), Z(0x59), Z(0x7c), Z(0x57), Z(0xc1), - Z(0x79), Z(0xc7), Z(0x34), Z(0xd6), Z(0x43), Z(0xdf), Z(0xe4), Z(0x78), - Z(0x16), Z(0x06), Z(0xda), Z(0x92), Z(0x76), Z(0x51), Z(0xe1), Z(0xd4), - Z(0x70), Z(0x03), Z(0xe0), Z(0x2f), Z(0x96), Z(0x91), Z(0x82), Z(0x80) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 11) -static const u32 sbox2[256] = { - Z(0xf0), Z(0x37), Z(0x24), Z(0x53), Z(0x2a), Z(0x03), Z(0x83), Z(0x86), - Z(0xd1), Z(0xec), Z(0x50), Z(0xf0), Z(0x42), Z(0x78), Z(0x2f), Z(0x6d), - Z(0xbf), Z(0x80), Z(0x87), Z(0x27), Z(0x95), Z(0xe2), Z(0xc5), Z(0x5d), - Z(0xf9), Z(0x6f), Z(0xdb), Z(0xb4), Z(0x65), Z(0x6e), Z(0xe7), Z(0x24), - Z(0xc8), Z(0x1a), Z(0xbb), Z(0x49), Z(0xb5), Z(0x0a), Z(0x7d), Z(0xb9), - Z(0xe8), Z(0xdc), Z(0xb7), Z(0xd9), Z(0x45), Z(0x20), Z(0x1b), Z(0xce), - Z(0x59), Z(0x9d), Z(0x6b), Z(0xbd), Z(0x0e), Z(0x8f), Z(0xa3), Z(0xa9), - Z(0xbc), Z(0x74), Z(0xa6), Z(0xf6), Z(0x7f), Z(0x5f), Z(0xb1), Z(0x68), - Z(0x84), Z(0xbc), Z(0xa9), Z(0xfd), Z(0x55), Z(0x50), Z(0xe9), Z(0xb6), - Z(0x13), Z(0x5e), Z(0x07), Z(0xb8), Z(0x95), Z(0x02), Z(0xc0), Z(0xd0), - Z(0x6a), Z(0x1a), Z(0x85), Z(0xbd), Z(0xb6), Z(0xfd), Z(0xfe), Z(0x17), - Z(0x3f), Z(0x09), Z(0xa3), Z(0x8d), Z(0xfb), Z(0xed), Z(0xda), Z(0x1d), - Z(0x6d), Z(0x1c), Z(0x6c), Z(0x01), Z(0x5a), Z(0xe5), Z(0x71), Z(0x3e), - Z(0x8b), Z(0x6b), Z(0xbe), Z(0x29), Z(0xeb), Z(0x12), Z(0x19), Z(0x34), - Z(0xcd), Z(0xb3), Z(0xbd), Z(0x35), Z(0xea), Z(0x4b), Z(0xd5), Z(0xae), - Z(0x2a), Z(0x79), Z(0x5a), Z(0xa5), Z(0x32), Z(0x12), Z(0x7b), Z(0xdc), - Z(0x2c), Z(0xd0), Z(0x22), Z(0x4b), Z(0xb1), Z(0x85), Z(0x59), Z(0x80), - Z(0xc0), Z(0x30), Z(0x9f), Z(0x73), Z(0xd3), Z(0x14), Z(0x48), Z(0x40), - Z(0x07), Z(0x2d), Z(0x8f), Z(0x80), Z(0x0f), Z(0xce), Z(0x0b), Z(0x5e), - Z(0xb7), Z(0x5e), Z(0xac), Z(0x24), Z(0x94), Z(0x4a), Z(0x18), Z(0x15), - Z(0x05), Z(0xe8), Z(0x02), Z(0x77), Z(0xa9), Z(0xc7), Z(0x40), Z(0x45), - Z(0x89), Z(0xd1), Z(0xea), Z(0xde), Z(0x0c), Z(0x79), Z(0x2a), Z(0x99), - Z(0x6c), Z(0x3e), Z(0x95), Z(0xdd), Z(0x8c), Z(0x7d), Z(0xad), Z(0x6f), - Z(0xdc), Z(0xff), Z(0xfd), Z(0x62), Z(0x47), Z(0xb3), Z(0x21), Z(0x8a), - Z(0xec), Z(0x8e), Z(0x19), Z(0x18), Z(0xb4), Z(0x6e), Z(0x3d), Z(0xfd), - Z(0x74), Z(0x54), Z(0x1e), Z(0x04), Z(0x85), Z(0xd8), Z(0xbc), Z(0x1f), - Z(0x56), Z(0xe7), Z(0x3a), Z(0x56), Z(0x67), Z(0xd6), Z(0xc8), Z(0xa5), - Z(0xf3), Z(0x8e), Z(0xde), Z(0xae), Z(0x37), Z(0x49), Z(0xb7), Z(0xfa), - Z(0xc8), Z(0xf4), Z(0x1f), Z(0xe0), Z(0x2a), Z(0x9b), Z(0x15), Z(0xd1), - Z(0x34), Z(0x0e), Z(0xb5), Z(0xe0), Z(0x44), Z(0x78), Z(0x84), Z(0x59), - Z(0x56), Z(0x68), Z(0x77), Z(0xa5), Z(0x14), Z(0x06), Z(0xf5), Z(0x2f), - Z(0x8c), Z(0x8a), Z(0x73), Z(0x80), Z(0x76), Z(0xb4), Z(0x10), Z(0x86) -}; - -#undef Z -#define Z(x) __constant_be32_to_cpu(x << 19) -static const u32 sbox3[256] = { - Z(0xa9), Z(0x2a), Z(0x48), Z(0x51), Z(0x84), Z(0x7e), Z(0x49), Z(0xe2), - Z(0xb5), Z(0xb7), Z(0x42), Z(0x33), Z(0x7d), Z(0x5d), Z(0xa6), Z(0x12), - Z(0x44), Z(0x48), Z(0x6d), Z(0x28), Z(0xaa), Z(0x20), Z(0x6d), Z(0x57), - Z(0xd6), Z(0x6b), Z(0x5d), Z(0x72), Z(0xf0), Z(0x92), Z(0x5a), Z(0x1b), - Z(0x53), Z(0x80), Z(0x24), Z(0x70), Z(0x9a), Z(0xcc), Z(0xa7), Z(0x66), - Z(0xa1), Z(0x01), Z(0xa5), Z(0x41), Z(0x97), Z(0x41), Z(0x31), Z(0x82), - Z(0xf1), Z(0x14), Z(0xcf), Z(0x53), Z(0x0d), Z(0xa0), Z(0x10), Z(0xcc), - Z(0x2a), Z(0x7d), Z(0xd2), Z(0xbf), Z(0x4b), Z(0x1a), Z(0xdb), Z(0x16), - Z(0x47), Z(0xf6), Z(0x51), Z(0x36), Z(0xed), Z(0xf3), Z(0xb9), Z(0x1a), - Z(0xa7), Z(0xdf), Z(0x29), Z(0x43), Z(0x01), Z(0x54), Z(0x70), Z(0xa4), - Z(0xbf), Z(0xd4), Z(0x0b), Z(0x53), Z(0x44), Z(0x60), Z(0x9e), Z(0x23), - Z(0xa1), Z(0x18), Z(0x68), Z(0x4f), Z(0xf0), Z(0x2f), Z(0x82), Z(0xc2), - Z(0x2a), Z(0x41), Z(0xb2), Z(0x42), Z(0x0c), Z(0xed), Z(0x0c), Z(0x1d), - Z(0x13), Z(0x3a), Z(0x3c), Z(0x6e), Z(0x35), Z(0xdc), Z(0x60), Z(0x65), - Z(0x85), Z(0xe9), Z(0x64), Z(0x02), Z(0x9a), Z(0x3f), Z(0x9f), Z(0x87), - Z(0x96), Z(0xdf), Z(0xbe), Z(0xf2), Z(0xcb), Z(0xe5), Z(0x6c), Z(0xd4), - Z(0x5a), Z(0x83), Z(0xbf), Z(0x92), Z(0x1b), Z(0x94), Z(0x00), Z(0x42), - Z(0xcf), Z(0x4b), Z(0x00), Z(0x75), Z(0xba), Z(0x8f), Z(0x76), Z(0x5f), - Z(0x5d), Z(0x3a), Z(0x4d), Z(0x09), Z(0x12), Z(0x08), Z(0x38), Z(0x95), - Z(0x17), Z(0xe4), Z(0x01), Z(0x1d), Z(0x4c), Z(0xa9), Z(0xcc), Z(0x85), - Z(0x82), Z(0x4c), Z(0x9d), Z(0x2f), Z(0x3b), Z(0x66), Z(0xa1), Z(0x34), - Z(0x10), Z(0xcd), Z(0x59), Z(0x89), Z(0xa5), Z(0x31), Z(0xcf), Z(0x05), - Z(0xc8), Z(0x84), Z(0xfa), Z(0xc7), Z(0xba), Z(0x4e), Z(0x8b), Z(0x1a), - Z(0x19), Z(0xf1), Z(0xa1), Z(0x3b), Z(0x18), Z(0x12), Z(0x17), Z(0xb0), - Z(0x98), Z(0x8d), Z(0x0b), Z(0x23), Z(0xc3), Z(0x3a), Z(0x2d), Z(0x20), - Z(0xdf), Z(0x13), Z(0xa0), Z(0xa8), Z(0x4c), Z(0x0d), Z(0x6c), Z(0x2f), - Z(0x47), Z(0x13), Z(0x13), Z(0x52), Z(0x1f), Z(0x2d), Z(0xf5), Z(0x79), - Z(0x3d), Z(0xa2), Z(0x54), Z(0xbd), Z(0x69), Z(0xc8), Z(0x6b), Z(0xf3), - Z(0x05), Z(0x28), Z(0xf1), Z(0x16), Z(0x46), Z(0x40), Z(0xb0), Z(0x11), - Z(0xd3), Z(0xb7), Z(0x95), Z(0x49), Z(0xcf), Z(0xc3), Z(0x1d), Z(0x8f), - Z(0xd8), Z(0xe1), Z(0x73), Z(0xdb), Z(0xad), Z(0xc8), Z(0xc9), Z(0xa9), - Z(0xa1), Z(0xc2), Z(0xc5), Z(0xe3), Z(0xba), Z(0xfc), Z(0x0e), Z(0x25) -}; - -/* - * This is a 16 round Feistel network with permutation F_ENCRYPT - */ -#define F_ENCRYPT(R, L, sched) \ -do { \ - union lc4 { u32 l; u8 c[4]; } u; \ - u.l = sched ^ R; \ - L ^= sbox0[u.c[0]] ^ sbox1[u.c[1]] ^ sbox2[u.c[2]] ^ sbox3[u.c[3]]; \ -} while(0) - -/* - * encryptor - */ -static void fcrypt_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - struct { - u32 l, r; - } X; - - memcpy(&X, src, sizeof(X)); - - F_ENCRYPT(X.r, X.l, ctx->sched[0x0]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x1]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x2]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x3]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x4]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x5]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x6]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x7]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x8]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x9]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xa]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xb]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xc]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xd]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xe]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xf]); - - memcpy(dst, &X, sizeof(X)); -} - -/* - * decryptor - */ -static void fcrypt_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - const struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - struct { - u32 l, r; - } X; - - memcpy(&X, src, sizeof(X)); - - F_ENCRYPT(X.l, X.r, ctx->sched[0xf]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xe]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xd]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xc]); - F_ENCRYPT(X.l, X.r, ctx->sched[0xb]); - F_ENCRYPT(X.r, X.l, ctx->sched[0xa]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x9]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x8]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x7]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x6]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x5]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x4]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x3]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x2]); - F_ENCRYPT(X.l, X.r, ctx->sched[0x1]); - F_ENCRYPT(X.r, X.l, ctx->sched[0x0]); - - memcpy(dst, &X, sizeof(X)); -} - -/* - * Generate a key schedule from key, the least significant bit in each key byte - * is parity and shall be ignored. This leaves 56 significant bits in the key - * to scatter over the 16 key schedules. For each schedule extract the low - * order 32 bits and use as schedule, then rotate right by 11 bits. - */ -static int fcrypt_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) -{ - struct fcrypt_ctx *ctx = crypto_tfm_ctx(tfm); - -#if BITS_PER_LONG == 64 /* the 64-bit version can also be used for 32-bit - * kernels - it seems to be faster but the code is - * larger */ - - u64 k; /* k holds all 56 non-parity bits */ - - /* discard the parity bits */ - k = (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key++) >> 1; - k <<= 7; - k |= (*key) >> 1; - - /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */ - ctx->sched[0x0] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x1] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x2] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x3] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x4] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x5] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x6] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x7] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x8] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0x9] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xa] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xb] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xc] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xd] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xe] = be32_to_cpu(k); ror56_64(k, 11); - ctx->sched[0xf] = be32_to_cpu(k); - - return 0; -#else - u32 hi, lo; /* hi is upper 24 bits and lo lower 32, total 56 */ - - /* discard the parity bits */ - lo = (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - hi = lo >> 4; - lo &= 0xf; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key++) >> 1; - lo <<= 7; - lo |= (*key) >> 1; - - /* Use lower 32 bits for schedule, rotate by 11 each round (16 times) */ - ctx->sched[0x0] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x1] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x2] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x3] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x4] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x5] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x6] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x7] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x8] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0x9] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xa] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xb] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xc] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xd] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xe] = be32_to_cpu(lo); ror56(hi, lo, 11); - ctx->sched[0xf] = be32_to_cpu(lo); - return 0; -#endif -} - -static struct crypto_alg fcrypt_alg = { - .cra_name = "fcrypt", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, - .cra_blocksize = 8, - .cra_ctxsize = sizeof(struct fcrypt_ctx), - .cra_module = THIS_MODULE, - .cra_alignmask = 3, - .cra_list = LIST_HEAD_INIT(fcrypt_alg.cra_list), - .cra_u = { .cipher = { - .cia_min_keysize = 8, - .cia_max_keysize = 8, - .cia_setkey = fcrypt_setkey, - .cia_encrypt = fcrypt_encrypt, - .cia_decrypt = fcrypt_decrypt } } -}; - -static int __init init(void) -{ - return crypto_register_alg(&fcrypt_alg); -} - -static void __exit fini(void) -{ - crypto_unregister_alg(&fcrypt_alg); -} - -module_init(init); -module_exit(fini); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("FCrypt Cipher Algorithm"); -MODULE_AUTHOR("David Howells "); diff --git a/trunk/crypto/hash.c b/trunk/crypto/hash.c index 12c4514f3478..cdec23d885fe 100644 --- a/trunk/crypto/hash.c +++ b/trunk/crypto/hash.c @@ -16,13 +16,12 @@ #include "internal.h" -static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type, - u32 mask) +static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg) { return alg->cra_ctxsize; } -static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask) +static int crypto_init_hash_ops(struct crypto_tfm *tfm) { struct hash_tfm *crt = &tfm->crt_hash; struct hash_alg *alg = &tfm->__crt_alg->cra_hash; diff --git a/trunk/crypto/hmac.c b/trunk/crypto/hmac.c index 44187c5ee593..b521bcd2b2c6 100644 --- a/trunk/crypto/hmac.c +++ b/trunk/crypto/hmac.c @@ -172,16 +172,15 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, static int hmac_init_tfm(struct crypto_tfm *tfm) { - struct crypto_hash *hash; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct hmac_ctx *ctx = hmac_ctx(__crypto_hash_cast(tfm)); - hash = crypto_spawn_hash(spawn); - if (IS_ERR(hash)) - return PTR_ERR(hash); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - ctx->child = hash; + ctx->child = crypto_hash_cast(tfm); return 0; } diff --git a/trunk/crypto/internal.h b/trunk/crypto/internal.h index 60acad9788c5..2da6ad4f3593 100644 --- a/trunk/crypto/internal.h +++ b/trunk/crypto/internal.h @@ -83,7 +83,8 @@ static inline void crypto_exit_proc(void) { } #endif -static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, + int flags) { unsigned int len = alg->cra_ctxsize; @@ -95,12 +96,23 @@ static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg) return len; } -static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, + int flags) { - return alg->cra_ctxsize; + unsigned int len = alg->cra_ctxsize; + + switch (flags & CRYPTO_TFM_MODE_MASK) { + case CRYPTO_TFM_MODE_CBC: + len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1); + len += alg->cra_blocksize; + break; + } + + return len; } -static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg) +static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg, + int flags) { return alg->cra_ctxsize; } @@ -109,6 +121,10 @@ struct crypto_alg *crypto_mod_get(struct crypto_alg *alg); struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask); struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); + int crypto_init_digest_ops(struct crypto_tfm *tfm); int crypto_init_cipher_ops(struct crypto_tfm *tfm); int crypto_init_compress_ops(struct crypto_tfm *tfm); @@ -120,8 +136,7 @@ void crypto_exit_compress_ops(struct crypto_tfm *tfm); void crypto_larval_error(const char *name, u32 type, u32 mask); void crypto_shoot_alg(struct crypto_alg *alg); -struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, - u32 mask); +struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags); int crypto_register_instance(struct crypto_template *tmpl, struct crypto_instance *inst); diff --git a/trunk/crypto/lrw.c b/trunk/crypto/lrw.c index b4105080ac7a..56642586d84f 100644 --- a/trunk/crypto/lrw.c +++ b/trunk/crypto/lrw.c @@ -201,22 +201,21 @@ static int decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, static int init_tfm(struct crypto_tfm *tfm) { - struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct priv *ctx = crypto_tfm_ctx(tfm); u32 *flags = &tfm->crt_flags; - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - if (crypto_cipher_blocksize(cipher) != 16) { + if (crypto_tfm_alg_blocksize(tfm) != 16) { *flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; return -EINVAL; } - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); return 0; } diff --git a/trunk/crypto/pcbc.c b/trunk/crypto/pcbc.c deleted file mode 100644 index 5174d7fdad6e..000000000000 --- a/trunk/crypto/pcbc.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * PCBC: Propagating Cipher Block Chaining mode - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * Derived from cbc.c - * - Copyright (c) 2006 Herbert Xu - * - * 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 -#include -#include -#include -#include -#include -#include - -struct crypto_pcbc_ctx { - struct crypto_cipher *child; - void (*xor)(u8 *dst, const u8 *src, unsigned int bs); -}; - -static int crypto_pcbc_setkey(struct crypto_tfm *parent, const u8 *key, - unsigned int keylen) -{ - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(parent); - struct crypto_cipher *child = ctx->child; - int err; - - crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); - crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) & - CRYPTO_TFM_REQ_MASK); - err = crypto_cipher_setkey(child, key, keylen); - crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) & - CRYPTO_TFM_RES_MASK); - return err; -} - -static int crypto_pcbc_encrypt_segment(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_encrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - u8 *iv = walk->iv; - - do { - xor(iv, src, bsize); - fn(crypto_cipher_tfm(tfm), dst, iv); - memcpy(iv, dst, bsize); - xor(iv, src, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt_inplace(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_encrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *iv = walk->iv; - u8 tmpbuf[bsize]; - - do { - memcpy(tmpbuf, src, bsize); - xor(iv, tmpbuf, bsize); - fn(crypto_cipher_tfm(tfm), src, iv); - memcpy(iv, src, bsize); - xor(iv, tmpbuf, bsize); - - src += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_encrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct blkcipher_walk walk; - struct crypto_blkcipher *tfm = desc->tfm; - struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); - struct crypto_cipher *child = ctx->child; - void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_encrypt_inplace(desc, &walk, child, - xor); - else - nbytes = crypto_pcbc_encrypt_segment(desc, &walk, child, - xor); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static int crypto_pcbc_decrypt_segment(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_decrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *dst = walk->dst.virt.addr; - u8 *iv = walk->iv; - - do { - fn(crypto_cipher_tfm(tfm), dst, src); - xor(dst, iv, bsize); - memcpy(iv, src, bsize); - xor(iv, dst, bsize); - - src += bsize; - dst += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt_inplace(struct blkcipher_desc *desc, - struct blkcipher_walk *walk, - struct crypto_cipher *tfm, - void (*xor)(u8 *, const u8 *, - unsigned int)) -{ - void (*fn)(struct crypto_tfm *, u8 *, const u8 *) = - crypto_cipher_alg(tfm)->cia_decrypt; - int bsize = crypto_cipher_blocksize(tfm); - unsigned int nbytes = walk->nbytes; - u8 *src = walk->src.virt.addr; - u8 *iv = walk->iv; - u8 tmpbuf[bsize]; - - do { - memcpy(tmpbuf, src, bsize); - fn(crypto_cipher_tfm(tfm), src, src); - xor(src, iv, bsize); - memcpy(iv, tmpbuf, bsize); - xor(iv, src, bsize); - - src += bsize; - } while ((nbytes -= bsize) >= bsize); - - memcpy(walk->iv, iv, bsize); - - return nbytes; -} - -static int crypto_pcbc_decrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct blkcipher_walk walk; - struct crypto_blkcipher *tfm = desc->tfm; - struct crypto_pcbc_ctx *ctx = crypto_blkcipher_ctx(tfm); - struct crypto_cipher *child = ctx->child; - void (*xor)(u8 *, const u8 *, unsigned int bs) = ctx->xor; - int err; - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - if (walk.src.virt.addr == walk.dst.virt.addr) - nbytes = crypto_pcbc_decrypt_inplace(desc, &walk, child, - xor); - else - nbytes = crypto_pcbc_decrypt_segment(desc, &walk, child, - xor); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static void xor_byte(u8 *a, const u8 *b, unsigned int bs) -{ - do { - *a++ ^= *b++; - } while (--bs); -} - -static void xor_quad(u8 *dst, const u8 *src, unsigned int bs) -{ - u32 *a = (u32 *)dst; - u32 *b = (u32 *)src; - - do { - *a++ ^= *b++; - } while ((bs -= 4)); -} - -static void xor_64(u8 *a, const u8 *b, unsigned int bs) -{ - ((u32 *)a)[0] ^= ((u32 *)b)[0]; - ((u32 *)a)[1] ^= ((u32 *)b)[1]; -} - -static void xor_128(u8 *a, const u8 *b, unsigned int bs) -{ - ((u32 *)a)[0] ^= ((u32 *)b)[0]; - ((u32 *)a)[1] ^= ((u32 *)b)[1]; - ((u32 *)a)[2] ^= ((u32 *)b)[2]; - ((u32 *)a)[3] ^= ((u32 *)b)[3]; -} - -static int crypto_pcbc_init_tfm(struct crypto_tfm *tfm) -{ - struct crypto_instance *inst = (void *)tfm->__crt_alg; - struct crypto_spawn *spawn = crypto_instance_ctx(inst); - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm); - struct crypto_cipher *cipher; - - switch (crypto_tfm_alg_blocksize(tfm)) { - case 8: - ctx->xor = xor_64; - break; - - case 16: - ctx->xor = xor_128; - break; - - default: - if (crypto_tfm_alg_blocksize(tfm) % 4) - ctx->xor = xor_byte; - else - ctx->xor = xor_quad; - } - - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); - - ctx->child = cipher; - return 0; -} - -static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm) -{ - struct crypto_pcbc_ctx *ctx = crypto_tfm_ctx(tfm); - crypto_free_cipher(ctx->child); -} - -static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) -{ - struct crypto_instance *inst; - struct crypto_alg *alg; - - alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, - CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); - if (IS_ERR(alg)) - return ERR_PTR(PTR_ERR(alg)); - - inst = crypto_alloc_instance("pcbc", alg); - if (IS_ERR(inst)) - goto out_put_alg; - - inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER; - inst->alg.cra_priority = alg->cra_priority; - inst->alg.cra_blocksize = alg->cra_blocksize; - inst->alg.cra_alignmask = alg->cra_alignmask; - inst->alg.cra_type = &crypto_blkcipher_type; - - if (!(alg->cra_blocksize % 4)) - inst->alg.cra_alignmask |= 3; - inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize; - inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize; - inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize; - - inst->alg.cra_ctxsize = sizeof(struct crypto_pcbc_ctx); - - inst->alg.cra_init = crypto_pcbc_init_tfm; - inst->alg.cra_exit = crypto_pcbc_exit_tfm; - - inst->alg.cra_blkcipher.setkey = crypto_pcbc_setkey; - inst->alg.cra_blkcipher.encrypt = crypto_pcbc_encrypt; - inst->alg.cra_blkcipher.decrypt = crypto_pcbc_decrypt; - -out_put_alg: - crypto_mod_put(alg); - return inst; -} - -static void crypto_pcbc_free(struct crypto_instance *inst) -{ - crypto_drop_spawn(crypto_instance_ctx(inst)); - kfree(inst); -} - -static struct crypto_template crypto_pcbc_tmpl = { - .name = "pcbc", - .alloc = crypto_pcbc_alloc, - .free = crypto_pcbc_free, - .module = THIS_MODULE, -}; - -static int __init crypto_pcbc_module_init(void) -{ - return crypto_register_template(&crypto_pcbc_tmpl); -} - -static void __exit crypto_pcbc_module_exit(void) -{ - crypto_unregister_template(&crypto_pcbc_tmpl); -} - -module_init(crypto_pcbc_module_init); -module_exit(crypto_pcbc_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("PCBC block cipher algorithm"); diff --git a/trunk/crypto/tcrypt.c b/trunk/crypto/tcrypt.c index f5e9da319ece..d671e8942b1f 100644 --- a/trunk/crypto/tcrypt.c +++ b/trunk/crypto/tcrypt.c @@ -12,7 +12,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests * 2004-08-09 Added cipher speed tests (Reyk Floeter ) * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt * @@ -72,8 +71,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", - "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", NULL + "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", NULL }; static void hexdump(unsigned char *buf, unsigned int len) @@ -767,7 +765,7 @@ static void test_deflate(void) memcpy(tvmem, deflate_comp_tv_template, tsize); tv = (void *)tvmem; - tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_tfm("deflate", 0); if (tfm == NULL) { printk("failed to load transform for deflate\n"); return; @@ -966,26 +964,6 @@ static void do_test(void) test_cipher("ecb(xeta)", DECRYPT, xeta_dec_tv_template, XETA_DEC_TEST_VECTORS); - //FCrypt - test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template, - FCRYPT_ENC_TEST_VECTORS); - test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template, - FCRYPT_DEC_TEST_VECTORS); - - //CAMELLIA - test_cipher("ecb(camellia)", ENCRYPT, - camellia_enc_tv_template, - CAMELLIA_ENC_TEST_VECTORS); - test_cipher("ecb(camellia)", DECRYPT, - camellia_dec_tv_template, - CAMELLIA_DEC_TEST_VECTORS); - test_cipher("cbc(camellia)", ENCRYPT, - camellia_cbc_enc_tv_template, - CAMELLIA_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(camellia)", DECRYPT, - camellia_cbc_dec_tv_template, - CAMELLIA_CBC_DEC_TEST_VECTORS); - test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); test_hash("wp512", wp512_tv_template, WP512_TEST_VECTORS); @@ -1002,10 +980,6 @@ static void do_test(void) HMAC_SHA1_TEST_VECTORS); test_hash("hmac(sha256)", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS); - test_hash("hmac(sha384)", hmac_sha384_tv_template, - HMAC_SHA384_TEST_VECTORS); - test_hash("hmac(sha512)", hmac_sha512_tv_template, - HMAC_SHA512_TEST_VECTORS); test_hash("xcbc(aes)", aes_xcbc128_tv_template, XCBC_AES_TEST_VECTORS); @@ -1203,28 +1177,6 @@ static void do_test(void) XETA_DEC_TEST_VECTORS); break; - case 31: - test_cipher("pcbc(fcrypt)", ENCRYPT, fcrypt_pcbc_enc_tv_template, - FCRYPT_ENC_TEST_VECTORS); - test_cipher("pcbc(fcrypt)", DECRYPT, fcrypt_pcbc_dec_tv_template, - FCRYPT_DEC_TEST_VECTORS); - break; - - case 32: - test_cipher("ecb(camellia)", ENCRYPT, - camellia_enc_tv_template, - CAMELLIA_ENC_TEST_VECTORS); - test_cipher("ecb(camellia)", DECRYPT, - camellia_dec_tv_template, - CAMELLIA_DEC_TEST_VECTORS); - test_cipher("cbc(camellia)", ENCRYPT, - camellia_cbc_enc_tv_template, - CAMELLIA_CBC_ENC_TEST_VECTORS); - test_cipher("cbc(camellia)", DECRYPT, - camellia_cbc_dec_tv_template, - CAMELLIA_CBC_DEC_TEST_VECTORS); - break; - case 100: test_hash("hmac(md5)", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS); @@ -1240,16 +1192,6 @@ static void do_test(void) HMAC_SHA256_TEST_VECTORS); break; - case 103: - test_hash("hmac(sha384)", hmac_sha384_tv_template, - HMAC_SHA384_TEST_VECTORS); - break; - - case 104: - test_hash("hmac(sha512)", hmac_sha512_tv_template, - HMAC_SHA512_TEST_VECTORS); - break; - case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, @@ -1318,17 +1260,6 @@ static void do_test(void) des_speed_template); break; - case 205: - test_cipher_speed("ecb(camellia)", ENCRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("ecb(camellia)", DECRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("cbc(camellia)", ENCRYPT, sec, NULL, 0, - camellia_speed_template); - test_cipher_speed("cbc(camellia)", DECRYPT, sec, NULL, 0, - camellia_speed_template); - break; - case 300: /* fall through */ diff --git a/trunk/crypto/tcrypt.h b/trunk/crypto/tcrypt.h index 887527bd5bc6..48a81362cb85 100644 --- a/trunk/crypto/tcrypt.h +++ b/trunk/crypto/tcrypt.h @@ -12,7 +12,6 @@ * Software Foundation; either version 2 of the License, or (at your option) * any later version. * - * 2006-12-07 Added SHA384 HMAC and SHA512 HMAC tests * 2004-08-09 Cipher speed tests by Reyk Floeter * 2003-09-14 Changes by Kartikey Mahendra Bhatt * @@ -28,7 +27,7 @@ struct hash_testvec { /* only used with keyed hash algorithms */ - char key[132] __attribute__ ((__aligned__(4))); + char key[128] __attribute__ ((__aligned__(4))); char plaintext[240]; char digest[MAX_DIGEST_SIZE]; unsigned char tap[MAX_TAP]; @@ -1002,248 +1001,6 @@ static struct hash_testvec aes_xcbc128_tv_template[] = { } }; -/* - * SHA384 HMAC test vectors from RFC4231 - */ - -#define HMAC_SHA384_TEST_VECTORS 4 - -static struct hash_testvec hmac_sha384_tv_template[] = { - { - .key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes) - .ksize = 20, - .plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There") - .psize = 8, - .digest = { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, - 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, - 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6, - 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c, - 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f, - 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 }, - }, { - .key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe") - .ksize = 4, - .plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, - 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ") - 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?") - .psize = 28, - .digest = { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, - 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, - 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47, - 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e, - 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7, - 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 }, - .np = 4, - .tap = { 7, 7, 7, 7 } - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, - 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large") - 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz") - 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key") - 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First") - .psize = 54, - .digest = { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, - 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, - 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f, - 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, - 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82, - 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 }, - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u") - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, - 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th") - 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke") - 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, - 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t") - 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d") - 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee") - 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, - 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ") - 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, - 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use") - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al") - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.") - .psize = 152, - .digest = { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, - 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c, - 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a, - 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5, - 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d, - 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e }, - }, -}; - -/* - * SHA512 HMAC test vectors from RFC4231 - */ - -#define HMAC_SHA512_TEST_VECTORS 4 - -static struct hash_testvec hmac_sha512_tv_template[] = { - { - .key = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0b, 0x0b }, // (20 bytes) - .ksize = 20, - .plaintext = { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 }, // ("Hi There") - .psize = 8, - .digest = { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, - 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, - 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, - 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde, - 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, - 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, - 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, - 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 }, - }, { - .key = { 0x4a, 0x65, 0x66, 0x65 }, // ("Jefe") - .ksize = 4, - .plaintext = { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, - 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, // ("what do ya want ") - 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, - 0x69, 0x6e, 0x67, 0x3f }, // ("for nothing?") - .psize = 28, - .digest = { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, - 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, - 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, - 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54, - 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, - 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, - 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, - 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 }, - .np = 4, - .tap = { 7, 7, 7, 7 } - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69, - 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, // ("Test Using Large") - 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a, // ("r Than Block-Siz") - 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79, // ("e Key - Hash Key") - 0x20, 0x46, 0x69, 0x72, 0x73, 0x74 }, // (" First") - .psize = 54, - .digest = { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, - 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, - 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, - 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, - 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, - 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, - 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, - 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 }, - }, { - .key = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa }, // (131 bytes) - .ksize = 131, - .plaintext = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75, // ("This is a test u") - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c, - 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68, // ("sing a larger th") - 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65, // ("an block-size ke") - 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, - 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, // ("y and a larger t") - 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64, // ("han block-size d") - 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65, // ("ata. The key nee") - 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, - 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, // ("ds to be hashed ") - 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62, - 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65, // ("before being use") - 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c, // ("d by the HMAC al") - 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e }, // ("gorithm.") - .psize = 152, - .digest = { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, - 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd, - 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, - 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44, - 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1, - 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, - 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, - 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 }, - }, -}; - /* * DES test vectors. */ @@ -3559,278 +3316,6 @@ static struct cipher_testvec xeta_dec_tv_template[] = { } }; -/* - * FCrypt test vectors - */ -#define FCRYPT_ENC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_enc_tv_template) -#define FCRYPT_DEC_TEST_VECTORS ARRAY_SIZE(fcrypt_pcbc_dec_tv_template) - -static struct cipher_testvec fcrypt_pcbc_enc_tv_template[] = { - { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */ - .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .ilen = 8, - .result = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 }, - .rlen = 8, - }, { - .key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 }, - .ilen = 8, - .result = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 }, - .rlen = 8, - }, { /* From Arla */ - .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .klen = 8, - .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, - 0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84, - 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7, - 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, - 0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1, - 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef }, - .rlen = 48, - }, { - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .rlen = 48, - }, { /* split-page version */ - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = "The quick brown fox jumps over the lazy dogs.\0\0", - .ilen = 48, - .result = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .rlen = 48, - .np = 2, - .tap = { 20, 28 }, - } -}; - -static struct cipher_testvec fcrypt_pcbc_dec_tv_template[] = { - { /* http://www.openafs.org/pipermail/openafs-devel/2000-December/005320.html */ - .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0x0E, 0x09, 0x00, 0xC7, 0x3E, 0xF7, 0xED, 0x41 }, - .ilen = 8, - .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .rlen = 8, - }, { - .key = { 0x11, 0x44, 0x77, 0xAA, 0xDD, 0x00, 0x33, 0x66 }, - .klen = 8, - .iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - .input = { 0xD8, 0xED, 0x78, 0x74, 0x77, 0xEC, 0x06, 0x80 }, - .ilen = 8, - .result = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 }, - .rlen = 8, - }, { /* From Arla */ - .key = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .klen = 8, - .iv = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .input = { 0x00, 0xf0, 0xe, 0x11, 0x75, 0xe6, 0x23, 0x82, - 0xee, 0xac, 0x98, 0x62, 0x44, 0x51, 0xe4, 0x84, - 0xc3, 0x59, 0xd8, 0xaa, 0x64, 0x60, 0xae, 0xf7, - 0xd2, 0xd9, 0x13, 0x79, 0x72, 0xa3, 0x45, 0x03, - 0x23, 0xb5, 0x62, 0xd7, 0x0c, 0xf5, 0x27, 0xd1, - 0xf8, 0x91, 0x3c, 0xac, 0x44, 0x22, 0x92, 0xef }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - }, { - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - }, { /* split-page version */ - .key = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 8, - .iv = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }, - .input = { 0xca, 0x90, 0xf5, 0x9d, 0xcb, 0xd4, 0xd2, 0x3c, - 0x01, 0x88, 0x7f, 0x3e, 0x31, 0x6e, 0x62, 0x9d, - 0xd8, 0xe0, 0x57, 0xa3, 0x06, 0x3a, 0x42, 0x58, - 0x2a, 0x28, 0xfe, 0x72, 0x52, 0x2f, 0xdd, 0xe0, - 0x19, 0x89, 0x09, 0x1c, 0x2a, 0x8e, 0x8c, 0x94, - 0xfc, 0xc7, 0x68, 0xe4, 0x88, 0xaa, 0xde, 0x0f }, - .ilen = 48, - .result = "The quick brown fox jumps over the lazy dogs.\0\0", - .rlen = 48, - .np = 2, - .tap = { 20, 28 }, - } -}; - -/* - * CAMELLIA test vectors. - */ -#define CAMELLIA_ENC_TEST_VECTORS 3 -#define CAMELLIA_DEC_TEST_VECTORS 3 -#define CAMELLIA_CBC_ENC_TEST_VECTORS 2 -#define CAMELLIA_CBC_DEC_TEST_VECTORS 2 - -static struct cipher_testvec camellia_enc_tv_template[] = { - { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 16, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - .klen = 24, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - .klen = 32, - .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .ilen = 16, - .result = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - .rlen = 16, - }, -}; - -static struct cipher_testvec camellia_dec_tv_template[] = { - { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .klen = 16, - .input = { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, - 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, - .klen = 24, - .input = { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, - 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, { - .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, - .klen = 32, - .input = { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, - 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, - .ilen = 16, - .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, - .rlen = 16, - }, -}; - -static struct cipher_testvec camellia_cbc_enc_tv_template[] = { - { - .key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, - 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }, - .klen = 16, - .iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, - 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 }, - .input = { "Single block msg" }, - .ilen = 16, - .result = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7, - 0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 }, - .rlen = 16, - }, { - .key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, - 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a }, - .klen = 16, - .iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, - 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }, - .input = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - .ilen = 32, - .result = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01, - 0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd, - 0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0, - 0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 }, - .rlen = 32, - }, -}; - -static struct cipher_testvec camellia_cbc_dec_tv_template[] = { - { - .key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, - 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 }, - .klen = 16, - .iv = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30, - 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 }, - .input = { 0xea, 0x32, 0x12, 0x76, 0x3b, 0x50, 0x10, 0xe7, - 0x18, 0xf6, 0xfd, 0x5d, 0xf6, 0x8f, 0x13, 0x51 }, - .ilen = 16, - .result = { "Single block msg" }, - .rlen = 16, - }, { - .key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, - 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a }, - .klen = 16, - .iv = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, - 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 }, - .input = { 0xa5, 0xdf, 0x6e, 0x50, 0xda, 0x70, 0x6c, 0x01, - 0x4a, 0xab, 0xf3, 0xf2, 0xd6, 0xfc, 0x6c, 0xfd, - 0x19, 0xb4, 0x3e, 0x57, 0x1c, 0x02, 0x5e, 0xa0, - 0x15, 0x78, 0xe0, 0x5e, 0xf2, 0xcb, 0x87, 0x16 }, - .ilen = 32, - .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - .rlen = 32, - }, -}; - /* * Compression stuff. */ @@ -4284,25 +3769,4 @@ static struct hash_speed generic_hash_speed_template[] = { { .blen = 0, .plen = 0, } }; -static struct cipher_speed camellia_speed_template[] = { - { .klen = 16, .blen = 16, }, - { .klen = 16, .blen = 64, }, - { .klen = 16, .blen = 256, }, - { .klen = 16, .blen = 1024, }, - { .klen = 16, .blen = 8192, }, - { .klen = 24, .blen = 16, }, - { .klen = 24, .blen = 64, }, - { .klen = 24, .blen = 256, }, - { .klen = 24, .blen = 1024, }, - { .klen = 24, .blen = 8192, }, - { .klen = 32, .blen = 16, }, - { .klen = 32, .blen = 64, }, - { .klen = 32, .blen = 256, }, - { .klen = 32, .blen = 1024, }, - { .klen = 32, .blen = 8192, }, - - /* End marker */ - { .klen = 0, .blen = 0, } -}; - #endif /* _CRYPTO_TCRYPT_H */ diff --git a/trunk/crypto/xcbc.c b/trunk/crypto/xcbc.c index 53e8ccbf0f5f..9347eb6bcf69 100644 --- a/trunk/crypto/xcbc.c +++ b/trunk/crypto/xcbc.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -48,7 +47,7 @@ static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101, * +------------------------ */ struct crypto_xcbc_ctx { - struct crypto_cipher *child; + struct crypto_tfm *child; u8 *odds; u8 *prev; u8 *key; @@ -76,7 +75,8 @@ static int _crypto_xcbc_digest_setkey(struct crypto_hash *parent, if ((err = crypto_cipher_setkey(ctx->child, ctx->key, ctx->keylen))) return err; - crypto_cipher_encrypt_one(ctx->child, key1, ctx->consts); + ctx->child->__crt_alg->cra_cipher.cia_encrypt(ctx->child, key1, + ctx->consts); return crypto_cipher_setkey(ctx->child, key1, bs); } @@ -86,7 +86,7 @@ static int crypto_xcbc_digest_setkey(struct crypto_hash *parent, { struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - if (keylen != crypto_cipher_blocksize(ctx->child)) + if (keylen != crypto_tfm_alg_blocksize(ctx->child)) return -EINVAL; ctx->keylen = keylen; @@ -108,13 +108,13 @@ static int crypto_xcbc_digest_init(struct hash_desc *pdesc) return 0; } -static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, - struct scatterlist *sg, - unsigned int nbytes) +static int crypto_xcbc_digest_update(struct hash_desc *pdesc, + struct scatterlist *sg, + unsigned int nbytes) { struct crypto_hash *parent = pdesc->tfm; struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - struct crypto_cipher *tfm = ctx->child; + struct crypto_tfm *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); unsigned int i = 0; @@ -142,7 +142,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, offset += len; crypto_kunmap(p, 0); - crypto_yield(pdesc->flags); + crypto_yield(tfm->crt_flags); continue; } @@ -152,7 +152,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, p += bs - ctx->len; ctx->xor(ctx->prev, ctx->odds, bs); - crypto_cipher_encrypt_one(tfm, ctx->prev, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev); /* clearing the length */ ctx->len = 0; @@ -160,8 +160,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, /* encrypting the rest of data */ while (len > bs) { ctx->xor(ctx->prev, p, bs); - crypto_cipher_encrypt_one(tfm, ctx->prev, - ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, ctx->prev, ctx->prev); p += bs; len -= bs; } @@ -172,7 +171,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, ctx->len = len; } crypto_kunmap(p, 0); - crypto_yield(pdesc->flags); + crypto_yield(tfm->crt_flags); slen -= min(slen, ((unsigned int)(PAGE_SIZE)) - offset); offset = 0; pg++; @@ -184,20 +183,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, return 0; } -static int crypto_xcbc_digest_update(struct hash_desc *pdesc, - struct scatterlist *sg, - unsigned int nbytes) -{ - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - return crypto_xcbc_digest_update2(pdesc, sg, nbytes); -} - static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) { struct crypto_hash *parent = pdesc->tfm; struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); - struct crypto_cipher *tfm = ctx->child; + struct crypto_tfm *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); int err = 0; @@ -207,14 +197,13 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0) return err; - crypto_cipher_encrypt_one(tfm, key2, - (u8 *)(ctx->consts + bs)); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key2, (const u8*)(ctx->consts+bs)); ctx->xor(ctx->prev, ctx->odds, bs); ctx->xor(ctx->prev, key2, bs); _crypto_xcbc_digest_setkey(parent, ctx); - crypto_cipher_encrypt_one(tfm, out, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev); } else { u8 key3[bs]; unsigned int rlen; @@ -229,15 +218,14 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0) return err; - crypto_cipher_encrypt_one(tfm, key3, - (u8 *)(ctx->consts + bs * 2)); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, key3, (const u8*)(ctx->consts+bs*2)); ctx->xor(ctx->prev, ctx->odds, bs); ctx->xor(ctx->prev, key3, bs); _crypto_xcbc_digest_setkey(parent, ctx); - crypto_cipher_encrypt_one(tfm, out, ctx->prev); + tfm->__crt_alg->cra_cipher.cia_encrypt(tfm, out, ctx->prev); } return 0; @@ -246,25 +234,21 @@ static int crypto_xcbc_digest_final(struct hash_desc *pdesc, u8 *out) static int crypto_xcbc_digest(struct hash_desc *pdesc, struct scatterlist *sg, unsigned int nbytes, u8 *out) { - if (WARN_ON_ONCE(in_irq())) - return -EDEADLK; - crypto_xcbc_digest_init(pdesc); - crypto_xcbc_digest_update2(pdesc, sg, nbytes); + crypto_xcbc_digest_update(pdesc, sg, nbytes); return crypto_xcbc_digest_final(pdesc, out); } static int xcbc_init_tfm(struct crypto_tfm *tfm) { - struct crypto_cipher *cipher; struct crypto_instance *inst = (void *)tfm->__crt_alg; struct crypto_spawn *spawn = crypto_instance_ctx(inst); struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(__crypto_hash_cast(tfm)); int bs = crypto_hash_blocksize(__crypto_hash_cast(tfm)); - cipher = crypto_spawn_cipher(spawn); - if (IS_ERR(cipher)) - return PTR_ERR(cipher); + tfm = crypto_spawn_tfm(spawn); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); switch(bs) { case 16: @@ -274,7 +258,7 @@ static int xcbc_init_tfm(struct crypto_tfm *tfm) return -EINVAL; } - ctx->child = cipher; + ctx->child = crypto_cipher_cast(tfm); ctx->odds = (u8*)(ctx+1); ctx->prev = ctx->odds + bs; ctx->key = ctx->prev + bs; diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index 91082ce6f5d1..667fa1dfa1a3 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -296,7 +296,7 @@ static int bay_add(acpi_handle handle, int id) /* * Initialize bay device structure */ - new_bay = kzalloc(sizeof(*new_bay), GFP_ATOMIC); + new_bay = kzalloc(GFP_ATOMIC, sizeof(*new_bay)); INIT_LIST_HEAD(&new_bay->list); new_bay->handle = handle; new_bay->name = (char *)nbuffer.pointer; diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index e2796fb40eb7..48616c6fee9d 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1173,7 +1173,7 @@ static void ahci_host_intr(struct ata_port *ap) * dangerous, we need to know more about them. Print * more of it. */ - const __le32 *f = pp->rx_fis + RX_FIS_SDB; + const u32 *f = pp->rx_fis + RX_FIS_SDB; ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 5f4e82ade6cd..46d8a94669b4 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -116,7 +116,7 @@ static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) return 0xffffffffU; - return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -125,7 +125,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, { if (sc_reg > SCR_CONTROL) return; - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); + writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } @@ -262,7 +262,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) static u8 k2_stat_check_status(struct ata_port *ap) { - return readl((void __iomem *) ap->ioaddr.status_addr); + return readl((void *) ap->ioaddr.status_addr); } #ifdef CONFIG_PPC_OF diff --git a/trunk/drivers/char/watchdog/machzwd.c b/trunk/drivers/char/watchdog/machzwd.c index 4d730fdbd528..276577d08fba 100644 --- a/trunk/drivers/char/watchdog/machzwd.c +++ b/trunk/drivers/char/watchdog/machzwd.c @@ -325,7 +325,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return put_user(0, p); case WDIOC_KEEPALIVE: - zf_ping(NULL); + zf_ping(0); break; default: diff --git a/trunk/drivers/crypto/geode-aes.c b/trunk/drivers/crypto/geode-aes.c index 31ea405f2eeb..43a68398656f 100644 --- a/trunk/drivers/crypto/geode-aes.c +++ b/trunk/drivers/crypto/geode-aes.c @@ -457,7 +457,7 @@ static struct pci_driver geode_aes_driver = { static int __init geode_aes_init(void) { - return pci_register_driver(&geode_aes_driver); + return pci_module_init(&geode_aes_driver); } static void __exit diff --git a/trunk/drivers/hwmon/ams/ams-input.c b/trunk/drivers/hwmon/ams/ams-input.c index 18210164e307..f126aa485134 100644 --- a/trunk/drivers/hwmon/ams/ams-input.c +++ b/trunk/drivers/hwmon/ams/ams-input.c @@ -153,7 +153,7 @@ int ams_input_init(void) } /* Call with ams_info.lock held! */ -void ams_input_exit(void) +void ams_input_exit() { ams_input_disable(); device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick); diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c index 89e37283c836..0a7d1ab60e6d 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c @@ -567,7 +567,7 @@ void iser_rcv_completion(struct iser_desc *rx_desc, opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (opcode == ISCSI_OP_SCSI_CMD_RSP) { - itt = get_itt(hdr->itt); /* mask out cid and age bits */ + itt = hdr->itt & ISCSI_ITT_MASK; /* mask out cid and age bits */ if (!(itt < session->cmds_max)) iser_err("itt can't be matched to task!!!" "conn %p opcode %d cmds_max %d itt %d\n", @@ -625,7 +625,7 @@ void iser_snd_completion(struct iser_desc *tx_desc) /* this arithmetic is legal by libiscsi dd_data allocation */ mtask = (void *) ((long)(void *)tx_desc - sizeof(struct iscsi_mgmt_task)); - if (mtask->hdr->itt == RESERVED_ITT) { + if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { struct iscsi_session *session = conn->session; spin_lock(&conn->session->lock); diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c index c7db4032ef02..4358a0a78eaa 100644 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ b/trunk/drivers/input/touchscreen/ucb1400_ts.c @@ -83,7 +83,7 @@ struct ucb1400 { - struct snd_ac97 *ac97; + ac97_t *ac97; struct input_dev *ts_idev; int irq; diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index 099f0afd394d..b10972ed0c9f 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -62,7 +62,7 @@ static struct kvm_stats_debugfs_item { { "halt_exits", &kvm_stat.halt_exits }, { "request_irq", &kvm_stat.request_irq_exits }, { "irq_exits", &kvm_stat.irq_exits }, - { NULL, NULL } + { 0, 0 } }; static struct dentry *debugfs_dir; @@ -205,7 +205,7 @@ static struct kvm_vcpu *vcpu_load(struct kvm *kvm, int vcpu_slot) mutex_lock(&vcpu->mutex); if (unlikely(!vcpu->vmcs)) { mutex_unlock(&vcpu->mutex); - return NULL; + return 0; } return kvm_arch_ops->vcpu_load(vcpu); } @@ -257,9 +257,9 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free, if (!dont || free->dirty_bitmap != dont->dirty_bitmap) vfree(free->dirty_bitmap); - free->phys_mem = NULL; + free->phys_mem = 0; free->npages = 0; - free->dirty_bitmap = NULL; + free->dirty_bitmap = 0; } static void kvm_free_physmem(struct kvm *kvm) @@ -267,7 +267,7 @@ static void kvm_free_physmem(struct kvm *kvm) int i; for (i = 0; i < kvm->nmemslots; ++i) - kvm_free_physmem_slot(&kvm->memslots[i], NULL); + kvm_free_physmem_slot(&kvm->memslots[i], 0); } static void kvm_free_vcpu(struct kvm_vcpu *vcpu) @@ -640,11 +640,11 @@ static int kvm_dev_ioctl_set_memory_region(struct kvm *kvm, /* Deallocate if slot is being removed */ if (!npages) - new.phys_mem = NULL; + new.phys_mem = 0; /* Free page dirty bitmap if unneeded */ if (!(new.flags & KVM_MEM_LOG_DIRTY_PAGES)) - new.dirty_bitmap = NULL; + new.dirty_bitmap = 0; r = -ENOMEM; @@ -799,14 +799,14 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) && gfn < memslot->base_gfn + memslot->npages) return memslot; } - return NULL; + return 0; } EXPORT_SYMBOL_GPL(gfn_to_memslot); void mark_page_dirty(struct kvm *kvm, gfn_t gfn) { int i; - struct kvm_memory_slot *memslot = NULL; + struct kvm_memory_slot *memslot = 0; unsigned long rel_gfn; for (i = 0; i < kvm->nmemslots; ++i) { @@ -1778,7 +1778,6 @@ static long kvm_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { struct kvm *kvm = filp->private_data; - void __user *argp = (void __user *)arg; int r = -EINVAL; switch (ioctl) { @@ -1795,12 +1794,12 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_run kvm_run; r = -EFAULT; - if (copy_from_user(&kvm_run, argp, sizeof kvm_run)) + if (copy_from_user(&kvm_run, (void *)arg, sizeof kvm_run)) goto out; r = kvm_dev_ioctl_run(kvm, &kvm_run); if (r < 0 && r != -EINTR) goto out; - if (copy_to_user(argp, &kvm_run, sizeof kvm_run)) { + if (copy_to_user((void *)arg, &kvm_run, sizeof kvm_run)) { r = -EFAULT; goto out; } @@ -1810,13 +1809,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_regs kvm_regs; r = -EFAULT; - if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + if (copy_from_user(&kvm_regs, (void *)arg, sizeof kvm_regs)) goto out; r = kvm_dev_ioctl_get_regs(kvm, &kvm_regs); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &kvm_regs, sizeof kvm_regs)) + if (copy_to_user((void *)arg, &kvm_regs, sizeof kvm_regs)) goto out; r = 0; break; @@ -1825,7 +1824,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_regs kvm_regs; r = -EFAULT; - if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + if (copy_from_user(&kvm_regs, (void *)arg, sizeof kvm_regs)) goto out; r = kvm_dev_ioctl_set_regs(kvm, &kvm_regs); if (r) @@ -1837,13 +1836,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_sregs kvm_sregs; r = -EFAULT; - if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) + if (copy_from_user(&kvm_sregs, (void *)arg, sizeof kvm_sregs)) goto out; r = kvm_dev_ioctl_get_sregs(kvm, &kvm_sregs); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &kvm_sregs, sizeof kvm_sregs)) + if (copy_to_user((void *)arg, &kvm_sregs, sizeof kvm_sregs)) goto out; r = 0; break; @@ -1852,7 +1851,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_sregs kvm_sregs; r = -EFAULT; - if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) + if (copy_from_user(&kvm_sregs, (void *)arg, sizeof kvm_sregs)) goto out; r = kvm_dev_ioctl_set_sregs(kvm, &kvm_sregs); if (r) @@ -1864,13 +1863,13 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_translation tr; r = -EFAULT; - if (copy_from_user(&tr, argp, sizeof tr)) + if (copy_from_user(&tr, (void *)arg, sizeof tr)) goto out; r = kvm_dev_ioctl_translate(kvm, &tr); if (r) goto out; r = -EFAULT; - if (copy_to_user(argp, &tr, sizeof tr)) + if (copy_to_user((void *)arg, &tr, sizeof tr)) goto out; r = 0; break; @@ -1879,7 +1878,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_interrupt irq; r = -EFAULT; - if (copy_from_user(&irq, argp, sizeof irq)) + if (copy_from_user(&irq, (void *)arg, sizeof irq)) goto out; r = kvm_dev_ioctl_interrupt(kvm, &irq); if (r) @@ -1891,7 +1890,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_debug_guest dbg; r = -EFAULT; - if (copy_from_user(&dbg, argp, sizeof dbg)) + if (copy_from_user(&dbg, (void *)arg, sizeof dbg)) goto out; r = kvm_dev_ioctl_debug_guest(kvm, &dbg); if (r) @@ -1903,7 +1902,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_memory_region kvm_mem; r = -EFAULT; - if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) + if (copy_from_user(&kvm_mem, (void *)arg, sizeof kvm_mem)) goto out; r = kvm_dev_ioctl_set_memory_region(kvm, &kvm_mem); if (r) @@ -1914,7 +1913,7 @@ static long kvm_dev_ioctl(struct file *filp, struct kvm_dirty_log log; r = -EFAULT; - if (copy_from_user(&log, argp, sizeof log)) + if (copy_from_user(&log, (void *)arg, sizeof log)) goto out; r = kvm_dev_ioctl_get_dirty_log(kvm, &log); if (r) @@ -1922,13 +1921,13 @@ static long kvm_dev_ioctl(struct file *filp, break; } case KVM_GET_MSRS: - r = msr_io(kvm, argp, get_msr, 1); + r = msr_io(kvm, (void __user *)arg, get_msr, 1); break; case KVM_SET_MSRS: - r = msr_io(kvm, argp, do_set_msr, 0); + r = msr_io(kvm, (void __user *)arg, do_set_msr, 0); break; case KVM_GET_MSR_INDEX_LIST: { - struct kvm_msr_list __user *user_msr_list = argp; + struct kvm_msr_list __user *user_msr_list = (void __user *)arg; struct kvm_msr_list msr_list; unsigned n; @@ -2015,7 +2014,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val, * in vmx root mode. */ printk(KERN_INFO "kvm: exiting hardware virtualization\n"); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); } return NOTIFY_OK; } @@ -2029,7 +2028,7 @@ static __init void kvm_init_debug(void) { struct kvm_stats_debugfs_item *p; - debugfs_dir = debugfs_create_dir("kvm", NULL); + debugfs_dir = debugfs_create_dir("kvm", 0); for (p = debugfs_entries; p->name; ++p) p->dentry = debugfs_create_u32(p->name, 0444, debugfs_dir, p->data); @@ -2070,7 +2069,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) if (r < 0) return r; - on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1); register_reboot_notifier(&kvm_reboot_notifier); kvm_chardev_ops.owner = module; @@ -2085,7 +2084,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) out_free: unregister_reboot_notifier(&kvm_reboot_notifier); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); kvm_arch_ops->hardware_unsetup(); return r; } @@ -2095,7 +2094,7 @@ void kvm_exit_arch(void) misc_deregister(&kvm_dev); unregister_reboot_notifier(&kvm_reboot_notifier); - on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); kvm_arch_ops->hardware_unsetup(); kvm_arch_ops = NULL; } diff --git a/trunk/drivers/kvm/mmu.c b/trunk/drivers/kvm/mmu.c index be793770f31b..22c426cd8cb2 100644 --- a/trunk/drivers/kvm/mmu.c +++ b/trunk/drivers/kvm/mmu.c @@ -333,7 +333,7 @@ static void rmap_desc_remove_entry(struct kvm_vcpu *vcpu, for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) ; desc->shadow_ptes[i] = desc->shadow_ptes[j]; - desc->shadow_ptes[j] = NULL; + desc->shadow_ptes[j] = 0; if (j != 0) return; if (!prev_desc && !desc->more) diff --git a/trunk/drivers/kvm/svm.c b/trunk/drivers/kvm/svm.c index 85f61dd1e936..c79df79307ed 100644 --- a/trunk/drivers/kvm/svm.c +++ b/trunk/drivers/kvm/svm.c @@ -274,7 +274,7 @@ static void svm_hardware_disable(void *garbage) wrmsrl(MSR_VM_HSAVE_PA, 0); rdmsrl(MSR_EFER, efer); wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); - per_cpu(svm_data, raw_smp_processor_id()) = NULL; + per_cpu(svm_data, raw_smp_processor_id()) = 0; __free_page(svm_data->save_area); kfree(svm_data); } @@ -642,7 +642,7 @@ static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg) case VCPU_SREG_LDTR: return &save->ldtr; } BUG(); - return NULL; + return 0; } static u64 svm_get_segment_base(struct kvm_vcpu *vcpu, int seg) @@ -934,7 +934,7 @@ static int io_get_override(struct kvm_vcpu *vcpu, return 0; *addr_override = 0; - *seg = NULL; + *seg = 0; for (i = 0; i < ins_length; i++) switch (inst[i]) { case 0xf0: @@ -1087,7 +1087,7 @@ static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - if (emulate_instruction(vcpu, NULL, 0, 0) != EMULATE_DONE) + if (emulate_instruction(vcpu, 0, 0, 0) != EMULATE_DONE) printk(KERN_ERR "%s: failed\n", __FUNCTION__); return 1; } diff --git a/trunk/drivers/kvm/vmx.c b/trunk/drivers/kvm/vmx.c index 27e05a77e21a..54c35c0b3181 100644 --- a/trunk/drivers/kvm/vmx.c +++ b/trunk/drivers/kvm/vmx.c @@ -98,7 +98,7 @@ static struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr) for (i = 0; i < vcpu->nmsrs; ++i) if (vcpu->guest_msrs[i].index == msr) return &vcpu->guest_msrs[i]; - return NULL; + return 0; } static void vmcs_clear(struct vmcs *vmcs) diff --git a/trunk/drivers/macintosh/rack-meter.c b/trunk/drivers/macintosh/rack-meter.c index f83fad2a3ff4..5ed41fe84e57 100644 --- a/trunk/drivers/macintosh/rack-meter.c +++ b/trunk/drivers/macintosh/rack-meter.c @@ -171,11 +171,11 @@ static void rackmeter_setup_dbdma(struct rackmeter *rm) /* Make sure dbdma is reset */ DBDMA_DO_RESET(rm->dma_regs); - pr_debug("rackmeter: mark offset=0x%zx\n", + pr_debug("rackmeter: mark offset=0x%lx\n", offsetof(struct rackmeter_dma, mark)); - pr_debug("rackmeter: buf1 offset=0x%zx\n", + pr_debug("rackmeter: buf1 offset=0x%lx\n", offsetof(struct rackmeter_dma, buf1)); - pr_debug("rackmeter: buf2 offset=0x%zx\n", + pr_debug("rackmeter: buf2 offset=0x%lx\n", offsetof(struct rackmeter_dma, buf2)); /* Prepare 4 dbdma commands for the 2 buffers */ diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 0e948a5c5a03..f51e02fe3655 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -698,6 +698,7 @@ IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = { [ 0x29 ] = KEY_TEXT, [ 0x2a ] = KEY_MEDIA, [ 0x18 ] = KEY_EPG, + [ 0x27 ] = KEY_RECORD, }; EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey); diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index bdd6301d2a47..7243337b771a 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -1072,7 +1072,7 @@ static int usbvision_v4l2_ioctl(struct inode *inode, struct file *file, } -static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, +static ssize_t usbvision_v4l2_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct video_device *dev = video_devdata(file); diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index bedae4ad3f74..89bba277da5f 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -42,7 +42,7 @@ config SGI_IOC4 config TIFM_CORE tristate "TI Flash Media interface support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI + depends on EXPERIMENTAL help If you want support for Texas Instruments(R) Flash Media adapters you should select this option and then also choose an appropriate diff --git a/trunk/drivers/misc/lkdtm.c b/trunk/drivers/misc/lkdtm.c index 552b7957a92a..db9d7df75ae0 100644 --- a/trunk/drivers/misc/lkdtm.c +++ b/trunk/drivers/misc/lkdtm.c @@ -108,8 +108,8 @@ static struct jprobe lkdtm; static int lkdtm_parse_commandline(void); static void lkdtm_handler(void); -static char* cpoint_name; -static char* cpoint_type; +static char* cpoint_name = INVALID; +static char* cpoint_type = NONE; static int cpoint_count = DEFAULT_COUNT; static int recur_count = REC_NUM_DEFAULT; diff --git a/trunk/drivers/mmc/Kconfig b/trunk/drivers/mmc/Kconfig index 12af9c718764..4224686fdf2a 100644 --- a/trunk/drivers/mmc/Kconfig +++ b/trunk/drivers/mmc/Kconfig @@ -111,7 +111,7 @@ config MMC_IMX config MMC_TIFM_SD tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" - depends on MMC && EXPERIMENTAL && PCI + depends on MMC && EXPERIMENTAL select TIFM_CORE help Say Y here if you want to be able to access MMC/SD cards with diff --git a/trunk/drivers/net/3c503.c b/trunk/drivers/net/3c503.c index bc7e906571d3..7e34c4f07b70 100644 --- a/trunk/drivers/net/3c503.c +++ b/trunk/drivers/net/3c503.c @@ -600,7 +600,8 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring count -= semi_count; memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); } else { - memcpy_fromio(skb->data, base + ring_offset, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, base + ring_offset, count, 0); } return; } diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 4f2ffbd81dc1..ad92b6a76ee6 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2335,17 +2335,6 @@ config QLA3XXX To compile this driver as a module, choose M here: the module will be called qla3xxx. -config ATL1 - tristate "Attansic L1 Gigabit Ethernet support (EXPERIMENTAL)" - depends on NET_PCI && PCI && EXPERIMENTAL - select CRC32 - select MII - help - This driver supports the Attansic L1 gigabit ethernet adapter. - - To compile this driver as a module, choose M here. The module - will be called atl1. - endmenu # diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 33af833667da..0878e3df5174 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/ obj-$(CONFIG_CHELSIO_T3) += cxgb3/ obj-$(CONFIG_EHEA) += ehea/ obj-$(CONFIG_BONDING) += bonding/ -obj-$(CONFIG_ATL1) += atl1/ obj-$(CONFIG_GIANFAR) += gianfar_driver.o gianfar_driver-objs := gianfar.o \ diff --git a/trunk/drivers/net/ac3200.c b/trunk/drivers/net/ac3200.c index 644c408515df..c01f87f5bed7 100644 --- a/trunk/drivers/net/ac3200.c +++ b/trunk/drivers/net/ac3200.c @@ -327,7 +327,8 @@ static void ac_block_input(struct net_device *dev, int count, struct sk_buff *sk memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES*256, count); } else { - memcpy_fromio(skb->data, start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, start, count, 0); } } diff --git a/trunk/drivers/net/atl1/Makefile b/trunk/drivers/net/atl1/Makefile deleted file mode 100644 index a6b707e4e69e..000000000000 --- a/trunk/drivers/net/atl1/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_ATL1) += atl1.o -atl1-y += atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o diff --git a/trunk/drivers/net/atl1/atl1.h b/trunk/drivers/net/atl1/atl1.h deleted file mode 100644 index b1c6034e68fa..000000000000 --- a/trunk/drivers/net/atl1/atl1.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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. - */ - -#ifndef _ATL1_H_ -#define _ATL1_H_ - -#include -#include - -#include "atl1_hw.h" - -/* function prototypes needed by multiple files */ -s32 atl1_up(struct atl1_adapter *adapter); -void atl1_down(struct atl1_adapter *adapter); -int atl1_reset(struct atl1_adapter *adapter); -s32 atl1_setup_ring_resources(struct atl1_adapter *adapter); -void atl1_free_ring_resources(struct atl1_adapter *adapter); - -extern char atl1_driver_name[]; -extern char atl1_driver_version[]; -extern const struct ethtool_ops atl1_ethtool_ops; - -struct atl1_adapter; - -#define ATL1_MAX_INTR 3 - -#define ATL1_DEFAULT_TPD 256 -#define ATL1_MAX_TPD 1024 -#define ATL1_MIN_TPD 64 -#define ATL1_DEFAULT_RFD 512 -#define ATL1_MIN_RFD 128 -#define ATL1_MAX_RFD 2048 - -#define ATL1_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) -#define ATL1_RFD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_free_desc) -#define ATL1_TPD_DESC(R, i) ATL1_GET_DESC(R, i, struct tx_packet_desc) -#define ATL1_RRD_DESC(R, i) ATL1_GET_DESC(R, i, struct rx_return_desc) - -/* - * Some workarounds require millisecond delays and are run during interrupt - * context. Most notably, when establishing link, the phy may need tweaking - * but cannot process phy register reads/writes faster than millisecond - * intervals...and we establish link due to a "link status change" interrupt. - */ - -/* - * wrapper around a pointer to a socket buffer, - * so a DMA handle can be stored along with the buffer - */ -struct atl1_buffer { - struct sk_buff *skb; - u16 length; - u16 alloced; - dma_addr_t dma; -}; - -#define MAX_TX_BUF_LEN 0x3000 /* 12KB */ - -struct atl1_tpd_ring { - void *desc; /* pointer to the descriptor ring memory */ - dma_addr_t dma; /* physical adress of the descriptor ring */ - u16 size; /* length of descriptor ring in bytes */ - u16 count; /* number of descriptors in the ring */ - u16 hw_idx; /* hardware index */ - atomic_t next_to_clean; - atomic_t next_to_use; - struct atl1_buffer *buffer_info; -}; - -struct atl1_rfd_ring { - void *desc; - dma_addr_t dma; - u16 size; - u16 count; - atomic_t next_to_use; - u16 next_to_clean; - struct atl1_buffer *buffer_info; -}; - -struct atl1_rrd_ring { - void *desc; - dma_addr_t dma; - unsigned int size; - u16 count; - u16 next_to_use; - atomic_t next_to_clean; -}; - -struct atl1_ring_header { - void *desc; /* pointer to the descriptor ring memory */ - dma_addr_t dma; /* physical adress of the descriptor ring */ - unsigned int size; /* length of descriptor ring in bytes */ -}; - -struct atl1_cmb { - struct coals_msg_block *cmb; - dma_addr_t dma; -}; - -struct atl1_smb { - struct stats_msg_block *smb; - dma_addr_t dma; -}; - -/* Statistics counters */ -struct atl1_sft_stats { - u64 rx_packets; - u64 tx_packets; - u64 rx_bytes; - u64 tx_bytes; - u64 multicast; - u64 collisions; - u64 rx_errors; - u64 rx_length_errors; - u64 rx_crc_errors; - u64 rx_frame_errors; - u64 rx_fifo_errors; - u64 rx_missed_errors; - u64 tx_errors; - u64 tx_fifo_errors; - u64 tx_aborted_errors; - u64 tx_window_errors; - u64 tx_carrier_errors; - - u64 tx_pause; /* num Pause packet transmitted. */ - u64 excecol; /* num tx packets aborted due to excessive collisions. */ - u64 deffer; /* num deferred tx packets */ - u64 scc; /* num packets subsequently transmitted successfully w/ single prior collision. */ - u64 mcc; /* num packets subsequently transmitted successfully w/ multiple prior collisions. */ - u64 latecol; /* num tx packets w/ late collisions. */ - u64 tx_underun; /* num tx packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ - u64 tx_trunc; /* num tx packets truncated due to size exceeding MTU, regardless whether truncated by Selene or not. (The name doesn't really reflect the meaning in this case.) */ - u64 rx_pause; /* num Pause packets received. */ - u64 rx_rrd_ov; - u64 rx_trunc; -}; - -/* board specific private data structure */ -#define ATL1_REGS_LEN 8 - -/* Structure containing variables used by the shared code */ -struct atl1_hw { - u8 __iomem *hw_addr; - struct atl1_adapter *back; - enum atl1_dma_order dma_ord; - enum atl1_dma_rcb rcb_value; - enum atl1_dma_req_block dmar_block; - enum atl1_dma_req_block dmaw_block; - u8 preamble_len; - u8 max_retry; /* Retransmission maximum, after which the packet will be discarded */ - u8 jam_ipg; /* IPG to start JAM for collision based flow control in half-duplex mode. In units of 8-bit time */ - u8 ipgt; /* Desired back to back inter-packet gap. The default is 96-bit time */ - u8 min_ifg; /* Minimum number of IFG to enforce in between RX frames. Frame gap below such IFP is dropped */ - u8 ipgr1; /* 64bit Carrier-Sense window */ - u8 ipgr2; /* 96-bit IPG window */ - u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. Each TPD is 16 bytes long */ - u8 rfd_burst; /* Number of RFD to prefetch in cache-aligned burst. Each RFD is 12 bytes long */ - u8 rfd_fetch_gap; - u8 rrd_burst; /* Threshold number of RRDs that can be retired in a burst. Each RRD is 16 bytes long */ - u8 tpd_fetch_th; - u8 tpd_fetch_gap; - u16 tx_jumbo_task_th; - u16 txf_burst; /* Number of data bytes to read in a cache-aligned burst. Each SRAM entry is - 8 bytes long */ - u16 rx_jumbo_th; /* Jumbo packet size for non-VLAN packet. VLAN packets should add 4 bytes */ - u16 rx_jumbo_lkah; - u16 rrd_ret_timer; /* RRD retirement timer. Decrement by 1 after every 512ns passes. */ - u16 lcol; /* Collision Window */ - - u16 cmb_tpd; - u16 cmb_rrd; - u16 cmb_rx_timer; - u16 cmb_tx_timer; - u32 smb_timer; - u16 media_type; - u16 autoneg_advertised; - u16 pci_cmd_word; - - u16 mii_autoneg_adv_reg; - u16 mii_1000t_ctrl_reg; - - u32 mem_rang; - u32 txcw; - u32 max_frame_size; - u32 min_frame_size; - u32 mc_filter_type; - u32 num_mc_addrs; - u32 collision_delta; - u32 tx_packet_delta; - u16 phy_spd_default; - - u16 dev_rev; - u8 revision_id; - - /* spi flash */ - u8 flash_vendor; - - u8 dma_fairness; - u8 mac_addr[ETH_ALEN]; - u8 perm_mac_addr[ETH_ALEN]; - - /* bool phy_preamble_sup; */ - bool phy_configured; -}; - -struct atl1_adapter { - /* OS defined structs */ - struct net_device *netdev; - struct pci_dev *pdev; - struct net_device_stats net_stats; - struct atl1_sft_stats soft_stats; - - struct vlan_group *vlgrp; - u32 rx_buffer_len; - u32 wol; - u16 link_speed; - u16 link_duplex; - spinlock_t lock; - atomic_t irq_sem; - struct work_struct tx_timeout_task; - struct work_struct link_chg_task; - struct work_struct pcie_dma_to_rst_task; - struct timer_list watchdog_timer; - struct timer_list phy_config_timer; - bool phy_timer_pending; - - bool mac_disabled; - - /* All descriptor rings' memory */ - struct atl1_ring_header ring_header; - - /* TX */ - struct atl1_tpd_ring tpd_ring; - spinlock_t mb_lock; - - /* RX */ - struct atl1_rfd_ring rfd_ring; - struct atl1_rrd_ring rrd_ring; - u64 hw_csum_err; - u64 hw_csum_good; - - u32 gorcl; - u64 gorcl_old; - - /* Interrupt Moderator timer ( 2us resolution) */ - u16 imt; - /* Interrupt Clear timer (2us resolution) */ - u16 ict; - - /* MII interface info */ - struct mii_if_info mii; - - /* structs defined in atl1_hw.h */ - u32 bd_number; /* board number */ - bool pci_using_64; - struct atl1_hw hw; - struct atl1_smb smb; - struct atl1_cmb cmb; - - u32 pci_state[16]; -}; - -#endif /* _ATL1_H_ */ diff --git a/trunk/drivers/net/atl1/atl1_ethtool.c b/trunk/drivers/net/atl1/atl1_ethtool.c deleted file mode 100644 index c11c27798e5c..000000000000 --- a/trunk/drivers/net/atl1/atl1_ethtool.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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 -#include -#include -#include -#include -#include - -#include "atl1.h" - -struct atl1_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; - -#define ATL1_STAT(m) sizeof(((struct atl1_adapter *)0)->m), \ - offsetof(struct atl1_adapter, m) - -static struct atl1_stats atl1_gstrings_stats[] = { - {"rx_packets", ATL1_STAT(soft_stats.rx_packets)}, - {"tx_packets", ATL1_STAT(soft_stats.tx_packets)}, - {"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)}, - {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)}, - {"rx_errors", ATL1_STAT(soft_stats.rx_errors)}, - {"tx_errors", ATL1_STAT(soft_stats.tx_errors)}, - {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)}, - {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)}, - {"multicast", ATL1_STAT(soft_stats.multicast)}, - {"collisions", ATL1_STAT(soft_stats.collisions)}, - {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)}, - {"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)}, - {"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)}, - {"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)}, - {"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)}, - {"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)}, - {"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)}, - {"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)}, - {"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)}, - {"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)}, - {"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)}, - {"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)}, - {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)}, - {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)}, - {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)}, - {"tx_underun", ATL1_STAT(soft_stats.tx_underun)}, - {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)}, - {"tx_pause", ATL1_STAT(soft_stats.tx_pause)}, - {"rx_pause", ATL1_STAT(soft_stats.rx_pause)}, - {"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)}, - {"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)} -}; - -static void atl1_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 *data) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int i; - char *p; - - for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) { - p = (char *)adapter+atl1_gstrings_stats[i].stat_offset; - data[i] = (atl1_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; - } - -} - -static int atl1_get_stats_count(struct net_device *netdev) -{ - return ARRAY_SIZE(atl1_gstrings_stats); -} - -static int atl1_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - ecmd->supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_TP); - ecmd->advertising = ADVERTISED_TP; - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - ecmd->advertising |= ADVERTISED_Autoneg; - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) { - ecmd->advertising |= ADVERTISED_Autoneg; - ecmd->advertising |= - (ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full); - } - else - ecmd->advertising |= (ADVERTISED_1000baseT_Full); - } - ecmd->port = PORT_TP; - ecmd->phy_address = 0; - ecmd->transceiver = XCVR_INTERNAL; - - if (netif_carrier_ok(adapter->netdev)) { - u16 link_speed, link_duplex; - atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex); - ecmd->speed = link_speed; - if (link_duplex == FULL_DUPLEX) - ecmd->duplex = DUPLEX_FULL; - else - ecmd->duplex = DUPLEX_HALF; - } else { - ecmd->speed = -1; - ecmd->duplex = -1; - } - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - ecmd->autoneg = AUTONEG_ENABLE; - else - ecmd->autoneg = AUTONEG_DISABLE; - - return 0; -} - -static int atl1_set_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - u16 phy_data; - int ret_val = 0; - u16 old_media_type = hw->media_type; - - if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool shutting down adapter\n", - atl1_driver_name); - atl1_down(adapter); - } - - if (ecmd->autoneg == AUTONEG_ENABLE) - hw->media_type = MEDIA_TYPE_AUTO_SENSOR; - else { - if (ecmd->speed == SPEED_1000) { - if (ecmd->duplex != DUPLEX_FULL) { - printk(KERN_WARNING - "%s: can't force to 1000M half duplex\n", - atl1_driver_name); - ret_val = -EINVAL; - goto exit_sset; - } - hw->media_type = MEDIA_TYPE_1000M_FULL; - } else if (ecmd->speed == SPEED_100) { - if (ecmd->duplex == DUPLEX_FULL) { - hw->media_type = MEDIA_TYPE_100M_FULL; - } else - hw->media_type = MEDIA_TYPE_100M_HALF; - } else { - if (ecmd->duplex == DUPLEX_FULL) - hw->media_type = MEDIA_TYPE_10M_FULL; - else - hw->media_type = MEDIA_TYPE_10M_HALF; - } - } - switch (hw->media_type) { - case MEDIA_TYPE_AUTO_SENSOR: - ecmd->advertising = - ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_TP; - break; - case MEDIA_TYPE_1000M_FULL: - ecmd->advertising = - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_TP; - break; - default: - ecmd->advertising = 0; - break; - } - if (atl1_phy_setup_autoneg_adv(hw)) { - ret_val = -EINVAL; - printk(KERN_WARNING - "%s: invalid ethtool speed/duplex setting\n", - atl1_driver_name); - goto exit_sset; - } - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); -exit_sset: - if (ret_val) - hw->media_type = old_media_type; - - if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool starting adapter\n", - atl1_driver_name); - atl1_up(adapter); - } else if (!ret_val) { - printk(KERN_DEBUG "%s: ethtool resetting adapter\n", - atl1_driver_name); - atl1_reset(adapter); - } - return ret_val; -} - -static void atl1_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - strncpy(drvinfo->driver, atl1_driver_name, sizeof(drvinfo->driver)); - strncpy(drvinfo->version, atl1_driver_version, - sizeof(drvinfo->version)); - strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), - sizeof(drvinfo->bus_info)); - drvinfo->eedump_len = ATL1_EEDUMP_LEN; -} - -static void atl1_get_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; - wol->wolopts = 0; - if (adapter->wol & ATL1_WUFC_EX) - wol->wolopts |= WAKE_UCAST; - if (adapter->wol & ATL1_WUFC_MC) - wol->wolopts |= WAKE_MCAST; - if (adapter->wol & ATL1_WUFC_BC) - wol->wolopts |= WAKE_BCAST; - if (adapter->wol & ATL1_WUFC_MAG) - wol->wolopts |= WAKE_MAGIC; - return; -} - -static int atl1_set_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) - return -EOPNOTSUPP; - adapter->wol = 0; - if (wol->wolopts & WAKE_UCAST) - adapter->wol |= ATL1_WUFC_EX; - if (wol->wolopts & WAKE_MCAST) - adapter->wol |= ATL1_WUFC_MC; - if (wol->wolopts & WAKE_BCAST) - adapter->wol |= ATL1_WUFC_BC; - if (wol->wolopts & WAKE_MAGIC) - adapter->wol |= ATL1_WUFC_MAG; - return 0; -} - -static void atl1_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_tpd_ring *txdr = &adapter->tpd_ring; - struct atl1_rfd_ring *rxdr = &adapter->rfd_ring; - - ring->rx_max_pending = ATL1_MAX_RFD; - ring->tx_max_pending = ATL1_MAX_TPD; - ring->rx_mini_max_pending = 0; - ring->rx_jumbo_max_pending = 0; - ring->rx_pending = rxdr->count; - ring->tx_pending = txdr->count; - ring->rx_mini_pending = 0; - ring->rx_jumbo_pending = 0; -} - -static int atl1_set_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_tpd_ring *tpdr = &adapter->tpd_ring; - struct atl1_rrd_ring *rrdr = &adapter->rrd_ring; - struct atl1_rfd_ring *rfdr = &adapter->rfd_ring; - - struct atl1_tpd_ring tpd_old, tpd_new; - struct atl1_rfd_ring rfd_old, rfd_new; - struct atl1_rrd_ring rrd_old, rrd_new; - struct atl1_ring_header rhdr_old, rhdr_new; - int err; - - tpd_old = adapter->tpd_ring; - rfd_old = adapter->rfd_ring; - rrd_old = adapter->rrd_ring; - rhdr_old = adapter->ring_header; - - if (netif_running(adapter->netdev)) - atl1_down(adapter); - - rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD); - rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD : - rfdr->count; - rfdr->count = (rfdr->count + 3) & ~3; - rrdr->count = rfdr->count; - - tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD); - tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD : - tpdr->count; - tpdr->count = (tpdr->count + 3) & ~3; - - if (netif_running(adapter->netdev)) { - /* try to get new resources before deleting old */ - err = atl1_setup_ring_resources(adapter); - if (err) - goto err_setup_ring; - - /* - * save the new, restore the old in order to free it, - * then restore the new back again - */ - - rfd_new = adapter->rfd_ring; - rrd_new = adapter->rrd_ring; - tpd_new = adapter->tpd_ring; - rhdr_new = adapter->ring_header; - adapter->rfd_ring = rfd_old; - adapter->rrd_ring = rrd_old; - adapter->tpd_ring = tpd_old; - adapter->ring_header = rhdr_old; - atl1_free_ring_resources(adapter); - adapter->rfd_ring = rfd_new; - adapter->rrd_ring = rrd_new; - adapter->tpd_ring = tpd_new; - adapter->ring_header = rhdr_new; - - err = atl1_up(adapter); - if (err) - return err; - } - return 0; - -err_setup_ring: - adapter->rfd_ring = rfd_old; - adapter->rrd_ring = rrd_old; - adapter->tpd_ring = tpd_old; - adapter->ring_header = rhdr_old; - atl1_up(adapter); - return err; -} - -static void atl1_get_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *epause) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - epause->autoneg = AUTONEG_ENABLE; - } else { - epause->autoneg = AUTONEG_DISABLE; - } - epause->rx_pause = 1; - epause->tx_pause = 1; -} - -static int atl1_set_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *epause) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - epause->autoneg = AUTONEG_ENABLE; - } else { - epause->autoneg = AUTONEG_DISABLE; - } - - epause->rx_pause = 1; - epause->tx_pause = 1; - - return 0; -} - -static u32 atl1_get_rx_csum(struct net_device *netdev) -{ - return 1; -} - -static void atl1_get_strings(struct net_device *netdev, u32 stringset, - u8 *data) -{ - u8 *p = data; - int i; - - switch (stringset) { - case ETH_SS_STATS: - for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) { - memcpy(p, atl1_gstrings_stats[i].stat_string, - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } - break; - } -} - -static int atl1_nway_reset(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - - if (netif_running(netdev)) { - u16 phy_data; - atl1_down(adapter); - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) { - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - } else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = MII_CR_FULL_DUPLEX | - MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = MII_CR_FULL_DUPLEX | - MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - } - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); - atl1_up(adapter); - } - return 0; -} - -const struct ethtool_ops atl1_ethtool_ops = { - .get_settings = atl1_get_settings, - .set_settings = atl1_set_settings, - .get_drvinfo = atl1_get_drvinfo, - .get_wol = atl1_get_wol, - .set_wol = atl1_set_wol, - .get_ringparam = atl1_get_ringparam, - .set_ringparam = atl1_set_ringparam, - .get_pauseparam = atl1_get_pauseparam, - .set_pauseparam = atl1_set_pauseparam, - .get_rx_csum = atl1_get_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_hw_csum, - .get_link = ethtool_op_get_link, - .get_sg = ethtool_op_get_sg, - .set_sg = ethtool_op_set_sg, - .get_strings = atl1_get_strings, - .nway_reset = atl1_nway_reset, - .get_ethtool_stats = atl1_get_ethtool_stats, - .get_stats_count = atl1_get_stats_count, - .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, -}; diff --git a/trunk/drivers/net/atl1/atl1_hw.c b/trunk/drivers/net/atl1/atl1_hw.c deleted file mode 100644 index 08b2d785469d..000000000000 --- a/trunk/drivers/net/atl1/atl1_hw.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "atl1.h" - -/* - * Reset the transmit and receive units; mask and clear all interrupts. - * hw - Struct containing variables accessed by shared code - * return : ATL1_SUCCESS or idle status (if error) - */ -s32 atl1_reset_hw(struct atl1_hw *hw) -{ - u32 icr; - int i; - - /* - * Clear Interrupt mask to stop board from generating - * interrupts & Clear any pending interrupt events - */ - /* - * iowrite32(0, hw->hw_addr + REG_IMR); - * iowrite32(0xffffffff, hw->hw_addr + REG_ISR); - */ - - /* - * Issue Soft Reset to the MAC. This will reset the chip's - * transmit, receive, DMA. It will not effect - * the current PCI configuration. The global reset bit is self- - * clearing, and should clear within a microsecond. - */ - iowrite32(MASTER_CTRL_SOFT_RST, hw->hw_addr + REG_MASTER_CTRL); - ioread32(hw->hw_addr + REG_MASTER_CTRL); - - iowrite16(1, hw->hw_addr + REG_GPHY_ENABLE); - ioread16(hw->hw_addr + REG_GPHY_ENABLE); - - msleep(1); /* delay about 1ms */ - - /* Wait at least 10ms for All module to be Idle */ - for (i = 0; i < 10; i++) { - icr = ioread32(hw->hw_addr + REG_IDLE_STATUS); - if (!icr) - break; - msleep(1); /* delay 1 ms */ - cpu_relax(); /* FIXME: is this still the right way to do this? */ - } - - if (icr) { - printk (KERN_DEBUG "icr = %x\n", icr); - return icr; - } - - return ATL1_SUCCESS; -} - -/* function about EEPROM - * - * check_eeprom_exist - * return 0 if eeprom exist - */ -static int atl1_check_eeprom_exist(struct atl1_hw *hw) -{ - u32 value; - value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - if (value & SPI_FLASH_CTRL_EN_VPD) { - value &= ~SPI_FLASH_CTRL_EN_VPD; - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - } - - value = ioread16(hw->hw_addr + REG_PCIE_CAP_LIST); - return ((value & 0xFF00) == 0x6C00) ? 0 : 1; -} - -static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value) -{ - int i; - u32 control; - - if (offset & 3) - return false; /* address do not align */ - - iowrite32(0, hw->hw_addr + REG_VPD_DATA); - control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT; - iowrite32(control, hw->hw_addr + REG_VPD_CAP); - ioread32(hw->hw_addr + REG_VPD_CAP); - - for (i = 0; i < 10; i++) { - msleep(2); - control = ioread32(hw->hw_addr + REG_VPD_CAP); - if (control & VPD_CAP_VPD_FLAG) - break; - } - if (control & VPD_CAP_VPD_FLAG) { - *p_value = ioread32(hw->hw_addr + REG_VPD_DATA); - return true; - } - return false; /* timeout */ -} - -/* - * Reads the value from a PHY register - * hw - Struct containing variables accessed by shared code - * reg_addr - address of the PHY register to read - */ -s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data) -{ - u32 val; - int i; - - val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | - MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << - MDIO_CLK_SEL_SHIFT; - iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); - ioread32(hw->hw_addr + REG_MDIO_CTRL); - - for (i = 0; i < MDIO_WAIT_TIMES; i++) { - udelay(2); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - if (!(val & (MDIO_START | MDIO_BUSY))) { - *phy_data = (u16) val; - return ATL1_SUCCESS; - } - return ATL1_ERR_PHY; -} - -#define CUSTOM_SPI_CS_SETUP 2 -#define CUSTOM_SPI_CLK_HI 2 -#define CUSTOM_SPI_CLK_LO 2 -#define CUSTOM_SPI_CS_HOLD 2 -#define CUSTOM_SPI_CS_HI 3 - -static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf) -{ - int i; - u32 value; - - iowrite32(0, hw->hw_addr + REG_SPI_DATA); - iowrite32(addr, hw->hw_addr + REG_SPI_ADDR); - - value = SPI_FLASH_CTRL_WAIT_READY | - (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) << - SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI & - SPI_FLASH_CTRL_CLK_HI_MASK) << - SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO & - SPI_FLASH_CTRL_CLK_LO_MASK) << - SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD & - SPI_FLASH_CTRL_CS_HOLD_MASK) << - SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI & - SPI_FLASH_CTRL_CS_HI_MASK) << - SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) << - SPI_FLASH_CTRL_INS_SHIFT; - - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - - value |= SPI_FLASH_CTRL_START; - iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL); - ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - - for (i = 0; i < 10; i++) { - msleep(1); /* 1ms */ - value = ioread32(hw->hw_addr + REG_SPI_FLASH_CTRL); - if (!(value & SPI_FLASH_CTRL_START)) - break; - } - - if (value & SPI_FLASH_CTRL_START) - return false; - - *buf = ioread32(hw->hw_addr + REG_SPI_DATA); - - return true; -} - -/* - * get_permanent_address - * return 0 if get valid mac address, - */ -static int atl1_get_permanent_address(struct atl1_hw *hw) -{ - u32 addr[2]; - u32 i, control; - u16 reg; - u8 eth_addr[ETH_ALEN]; - bool key_valid; - - if (is_valid_ether_addr(hw->perm_mac_addr)) - return 0; - - /* init */ - addr[0] = addr[1] = 0; - - if (!atl1_check_eeprom_exist(hw)) { /* eeprom exist */ - reg = 0; - key_valid = false; - /* Read out all EEPROM content */ - i = 0; - while (1) { - if (atl1_read_eeprom(hw, i + 0x100, &control)) { - if (key_valid) { - if (reg == REG_MAC_STA_ADDR) - addr[0] = control; - else if (reg == (REG_MAC_STA_ADDR + 4)) - addr[1] = control; - key_valid = false; - } else if ((control & 0xff) == 0x5A) { - key_valid = true; - reg = (u16) (control >> 16); - } else - break; /* assume data end while encount an invalid KEYWORD */ - } else - break; /* read error */ - i += 4; - } - -/* - * The following 2 lines are the Attansic originals. Saving for posterity. - * *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]); - * *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]); - */ - *(u32 *) & eth_addr[2] = swab32(addr[0]); - *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]); - - if (is_valid_ether_addr(eth_addr)) { - memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); - return 0; - } - return 1; - } - - /* see if SPI FLAGS exist ? */ - addr[0] = addr[1] = 0; - reg = 0; - key_valid = false; - i = 0; - while (1) { - if (atl1_spi_read(hw, i + 0x1f000, &control)) { - if (key_valid) { - if (reg == REG_MAC_STA_ADDR) - addr[0] = control; - else if (reg == (REG_MAC_STA_ADDR + 4)) - addr[1] = control; - key_valid = false; - } else if ((control & 0xff) == 0x5A) { - key_valid = true; - reg = (u16) (control >> 16); - } else - break; /* data end */ - } else - break; /* read error */ - i += 4; - } - -/* - * The following 2 lines are the Attansic originals. Saving for posterity. - * *(u32 *) & eth_addr[2] = LONGSWAP(addr[0]); - * *(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]); - */ - *(u32 *) & eth_addr[2] = swab32(addr[0]); - *(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]); - if (is_valid_ether_addr(eth_addr)) { - memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN); - return 0; - } - return 1; -} - -/* - * Reads the adapter's MAC address from the EEPROM - * hw - Struct containing variables accessed by shared code - */ -s32 atl1_read_mac_addr(struct atl1_hw *hw) -{ - u16 i; - - if (atl1_get_permanent_address(hw)) - random_ether_addr(hw->perm_mac_addr); - - for (i = 0; i < ETH_ALEN; i++) - hw->mac_addr[i] = hw->perm_mac_addr[i]; - return ATL1_SUCCESS; -} - -/* - * Hashes an address to determine its location in the multicast table - * hw - Struct containing variables accessed by shared code - * mc_addr - the multicast address to hash - * - * atl1_hash_mc_addr - * purpose - * set hash value for a multicast address - * hash calcu processing : - * 1. calcu 32bit CRC for multicast address - * 2. reverse crc with MSB to LSB - */ -u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr) -{ - u32 crc32, value = 0; - int i; - - crc32 = ether_crc_le(6, mc_addr); - crc32 = ~crc32; - for (i = 0; i < 32; i++) - value |= (((crc32 >> i) & 1) << (31 - i)); - - return value; -} - -/* - * Sets the bit in the multicast table corresponding to the hash value. - * hw - Struct containing variables accessed by shared code - * hash_value - Multicast address hash value - */ -void atl1_hash_set(struct atl1_hw *hw, u32 hash_value) -{ - u32 hash_bit, hash_reg; - u32 mta; - - /* - * The HASH Table is a register array of 2 32-bit registers. - * It is treated like an array of 64 bits. We want to set - * bit BitArray[hash_value]. So we figure out what register - * the bit is in, read it, OR in the new bit, then write - * back the new value. The register is determined by the - * upper 7 bits of the hash value and the bit within that - * register are determined by the lower 5 bits of the value. - */ - hash_reg = (hash_value >> 31) & 0x1; - hash_bit = (hash_value >> 26) & 0x1F; - mta = ioread32((hw + REG_RX_HASH_TABLE) + (hash_reg << 2)); - mta |= (1 << hash_bit); - iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2)); -} - -/* - * Writes a value to a PHY register - * hw - Struct containing variables accessed by shared code - * reg_addr - address of the PHY register to write - * data - data to write to the PHY - */ -s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data) -{ - int i; - u32 val; - - val = ((u32) (phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT | - (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT | - MDIO_SUP_PREAMBLE | - MDIO_START | MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; - iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); - ioread32(hw->hw_addr + REG_MDIO_CTRL); - - for (i = 0; i < MDIO_WAIT_TIMES; i++) { - udelay(2); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - - if (!(val & (MDIO_START | MDIO_BUSY))) - return ATL1_SUCCESS; - - return ATL1_ERR_PHY; -} - -/* - * Make L001's PHY out of Power Saving State (bug) - * hw - Struct containing variables accessed by shared code - * when power on, L001's PHY always on Power saving State - * (Gigabit Link forbidden) - */ -static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) -{ - s32 ret; - ret = atl1_write_phy_reg(hw, 29, 0x0029); - if (ret) - return ret; - return atl1_write_phy_reg(hw, 30, 0); -} - -/* - *TODO: do something or get rid of this - */ -s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) -{ -/* s32 ret_val; - * u16 phy_data; - */ - -/* - ret_val = atl1_write_phy_reg(hw, ...); - ret_val = atl1_write_phy_reg(hw, ...); - .... -*/ - return ATL1_SUCCESS; -} - -/* - * Resets the PHY and make all config validate - * hw - Struct containing variables accessed by shared code - * - * Sets bit 15 and 12 of the MII Control regiser (for F001 bug) - */ -static s32 atl1_phy_reset(struct atl1_hw *hw) -{ - s32 ret_val; - u16 phy_data; - - if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || - hw->media_type == MEDIA_TYPE_1000M_FULL) - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; - else { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - } - - ret_val = atl1_write_phy_reg(hw, MII_BMCR, phy_data); - if (ret_val) { - u32 val; - int i; - /* pcie serdes link may be down! */ - printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", - atl1_driver_name); - - for (i = 0; i < 25; i++) { - msleep(1); - val = ioread32(hw->hw_addr + REG_MDIO_CTRL); - if (!(val & (MDIO_START | MDIO_BUSY))) - break; - } - - if ((val & (MDIO_START | MDIO_BUSY)) != 0) { - printk(KERN_WARNING - "%s: pcie link down at least for 25ms\n", - atl1_driver_name); - return ret_val; - } - } - return ATL1_SUCCESS; -} - -/* - * Configures PHY autoneg and flow control advertisement settings - * hw - Struct containing variables accessed by shared code - */ -s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw) -{ - s32 ret_val; - s16 mii_autoneg_adv_reg; - s16 mii_1000t_ctrl_reg; - - /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK; - - /* Read the MII 1000Base-T Control Register (Address 9). */ - mii_1000t_ctrl_reg = MII_AT001_CR_1000T_DEFAULT_CAP_MASK; - - /* - * First we clear all the 10/100 mb speed bits in the Auto-Neg - * Advertisement Register (Address 4) and the 1000 mb speed bits in - * the 1000Base-T Control Register (Address 9). - */ - mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK; - mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK; - - /* - * Need to parse media_type and set up - * the appropriate PHY registers. - */ - switch (hw->media_type) { - case MEDIA_TYPE_AUTO_SENSOR: - mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS | - MII_AR_10T_FD_CAPS | - MII_AR_100TX_HD_CAPS | - MII_AR_100TX_FD_CAPS); - mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS; - break; - - case MEDIA_TYPE_1000M_FULL: - mii_1000t_ctrl_reg |= MII_AT001_CR_1000T_FD_CAPS; - break; - - case MEDIA_TYPE_100M_FULL: - mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS; - break; - - case MEDIA_TYPE_100M_HALF: - mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS; - break; - - case MEDIA_TYPE_10M_FULL: - mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS; - break; - - default: - mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS; - break; - } - - /* flow control fixed to enable all */ - mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); - - hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; - hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg; - - ret_val = atl1_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg); - if (ret_val) - return ret_val; - - ret_val = atl1_write_phy_reg(hw, MII_AT001_CR, mii_1000t_ctrl_reg); - if (ret_val) - return ret_val; - - return ATL1_SUCCESS; -} - -/* - * Configures link settings. - * hw - Struct containing variables accessed by shared code - * Assumes the hardware has previously been reset and the - * transmitter and receiver are not enabled. - */ -static s32 atl1_setup_link(struct atl1_hw *hw) -{ - s32 ret_val; - - /* - * Options: - * PHY will advertise value(s) parsed from - * autoneg_advertised and fc - * no matter what autoneg is , We will not wait link result. - */ - ret_val = atl1_phy_setup_autoneg_adv(hw); - if (ret_val) { - printk(KERN_DEBUG "%s: error setting up autonegotiation\n", - atl1_driver_name); - return ret_val; - } - /* SW.Reset , En-Auto-Neg if needed */ - ret_val = atl1_phy_reset(hw); - if (ret_val) { - printk(KERN_DEBUG "%s: error resetting the phy\n", - atl1_driver_name); - return ret_val; - } - hw->phy_configured = true; - return ret_val; -} - -static struct atl1_spi_flash_dev flash_table[] = { -/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */ - {"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62}, - {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60}, - {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7}, -}; - -static void atl1_init_flash_opcode(struct atl1_hw *hw) -{ - if (hw->flash_vendor >= sizeof(flash_table) / sizeof(flash_table[0])) - hw->flash_vendor = 0; /* ATMEL */ - - /* Init OP table */ - iowrite8(flash_table[hw->flash_vendor].cmd_program, - hw->hw_addr + REG_SPI_FLASH_OP_PROGRAM); - iowrite8(flash_table[hw->flash_vendor].cmd_sector_erase, - hw->hw_addr + REG_SPI_FLASH_OP_SC_ERASE); - iowrite8(flash_table[hw->flash_vendor].cmd_chip_erase, - hw->hw_addr + REG_SPI_FLASH_OP_CHIP_ERASE); - iowrite8(flash_table[hw->flash_vendor].cmd_rdid, - hw->hw_addr + REG_SPI_FLASH_OP_RDID); - iowrite8(flash_table[hw->flash_vendor].cmd_wren, - hw->hw_addr + REG_SPI_FLASH_OP_WREN); - iowrite8(flash_table[hw->flash_vendor].cmd_rdsr, - hw->hw_addr + REG_SPI_FLASH_OP_RDSR); - iowrite8(flash_table[hw->flash_vendor].cmd_wrsr, - hw->hw_addr + REG_SPI_FLASH_OP_WRSR); - iowrite8(flash_table[hw->flash_vendor].cmd_read, - hw->hw_addr + REG_SPI_FLASH_OP_READ); -} - -/* - * Performs basic configuration of the adapter. - * hw - Struct containing variables accessed by shared code - * Assumes that the controller has previously been reset and is in a - * post-reset uninitialized state. Initializes multicast table, - * and Calls routines to setup link - * Leaves the transmit and receive units disabled and uninitialized. - */ -s32 atl1_init_hw(struct atl1_hw *hw) -{ - u32 ret_val = 0; - - /* Zero out the Multicast HASH table */ - iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE); - /* clear the old settings from the multicast hash table */ - iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2)); - - atl1_init_flash_opcode(hw); - - if (!hw->phy_configured) { - /* enable GPHY LinkChange Interrrupt */ - ret_val = atl1_write_phy_reg(hw, 18, 0xC00); - if (ret_val) - return ret_val; - /* make PHY out of power-saving state */ - ret_val = atl1_phy_leave_power_saving(hw); - if (ret_val) - return ret_val; - /* Call a subroutine to configure the link */ - ret_val = atl1_setup_link(hw); - } - return ret_val; -} - -/* - * Detects the current speed and duplex settings of the hardware. - * hw - Struct containing variables accessed by shared code - * speed - Speed of the connection - * duplex - Duplex setting of the connection - */ -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) -{ - s32 ret_val; - u16 phy_data; - - /* ; --- Read PHY Specific Status Register (17) */ - ret_val = atl1_read_phy_reg(hw, MII_AT001_PSSR, &phy_data); - if (ret_val) - return ret_val; - - if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED)) - return ATL1_ERR_PHY_RES; - - switch (phy_data & MII_AT001_PSSR_SPEED) { - case MII_AT001_PSSR_1000MBS: - *speed = SPEED_1000; - break; - case MII_AT001_PSSR_100MBS: - *speed = SPEED_100; - break; - case MII_AT001_PSSR_10MBS: - *speed = SPEED_10; - break; - default: - printk(KERN_DEBUG "%s: error getting speed\n", - atl1_driver_name); - return ATL1_ERR_PHY_SPEED; - break; - } - if (phy_data & MII_AT001_PSSR_DPLX) - *duplex = FULL_DUPLEX; - else - *duplex = HALF_DUPLEX; - - return ATL1_SUCCESS; -} - -void atl1_set_mac_addr(struct atl1_hw *hw) -{ - u32 value; - /* - * 00-0B-6A-F6-00-DC - * 0: 6AF600DC 1: 000B - * low dword - */ - value = (((u32) hw->mac_addr[2]) << 24) | - (((u32) hw->mac_addr[3]) << 16) | - (((u32) hw->mac_addr[4]) << 8) | (((u32) hw->mac_addr[5])); - iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR); - /* high dword */ - value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1])); - iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2)); -} diff --git a/trunk/drivers/net/atl1/atl1_hw.h b/trunk/drivers/net/atl1/atl1_hw.h deleted file mode 100644 index 100c09c66e64..000000000000 --- a/trunk/drivers/net/atl1/atl1_hw.h +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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. - * - * There are a lot of defines in here that are unused and/or have cryptic - * names. Please leave them alone, as they're the closest thing we have - * to a spec from Attansic at present. *ahem* -- CHS - */ - -#ifndef _ATL1_HW_H_ -#define _ATL1_HW_H_ - -#include -#include - -struct atl1_adapter; -struct atl1_hw; - -/* function prototypes needed by multiple files */ -s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw); -s32 atl1_write_phy_reg(struct atl1_hw *hw, u32 reg_addr, u16 phy_data); -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex); -s32 atl1_read_mac_addr(struct atl1_hw *hw); -s32 atl1_init_hw(struct atl1_hw *hw); -s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex); -s32 atl1_set_speed_and_duplex(struct atl1_hw *hw, u16 speed, u16 duplex); -u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr); -void atl1_hash_set(struct atl1_hw *hw, u32 hash_value); -s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data); -void atl1_set_mac_addr(struct atl1_hw *hw); -s32 atl1_phy_enter_power_saving(struct atl1_hw *hw); -s32 atl1_reset_hw(struct atl1_hw *hw); -void atl1_check_options(struct atl1_adapter *adapter); - -/* register definitions */ -#define REG_PCIE_CAP_LIST 0x58 - -#define REG_VPD_CAP 0x6C -#define VPD_CAP_ID_MASK 0xff -#define VPD_CAP_ID_SHIFT 0 -#define VPD_CAP_NEXT_PTR_MASK 0xFF -#define VPD_CAP_NEXT_PTR_SHIFT 8 -#define VPD_CAP_VPD_ADDR_MASK 0x7FFF -#define VPD_CAP_VPD_ADDR_SHIFT 16 -#define VPD_CAP_VPD_FLAG 0x80000000 - -#define REG_VPD_DATA 0x70 - -#define REG_SPI_FLASH_CTRL 0x200 -#define SPI_FLASH_CTRL_STS_NON_RDY 0x1 -#define SPI_FLASH_CTRL_STS_WEN 0x2 -#define SPI_FLASH_CTRL_STS_WPEN 0x80 -#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF -#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0 -#define SPI_FLASH_CTRL_INS_MASK 0x7 -#define SPI_FLASH_CTRL_INS_SHIFT 8 -#define SPI_FLASH_CTRL_START 0x800 -#define SPI_FLASH_CTRL_EN_VPD 0x2000 -#define SPI_FLASH_CTRL_LDSTART 0x8000 -#define SPI_FLASH_CTRL_CS_HI_MASK 0x3 -#define SPI_FLASH_CTRL_CS_HI_SHIFT 16 -#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3 -#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18 -#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3 -#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20 -#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3 -#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22 -#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3 -#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24 -#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3 -#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26 -#define SPI_FLASH_CTRL_WAIT_READY 0x10000000 - -#define REG_SPI_ADDR 0x204 - -#define REG_SPI_DATA 0x208 - -#define REG_SPI_FLASH_CONFIG 0x20C -#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF -#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0 -#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3 -#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24 -#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000 - -#define REG_SPI_FLASH_OP_PROGRAM 0x210 -#define REG_SPI_FLASH_OP_SC_ERASE 0x211 -#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212 -#define REG_SPI_FLASH_OP_RDID 0x213 -#define REG_SPI_FLASH_OP_WREN 0x214 -#define REG_SPI_FLASH_OP_RDSR 0x215 -#define REG_SPI_FLASH_OP_WRSR 0x216 -#define REG_SPI_FLASH_OP_READ 0x217 - -#define REG_TWSI_CTRL 0x218 -#define TWSI_CTRL_LD_OFFSET_MASK 0xFF -#define TWSI_CTRL_LD_OFFSET_SHIFT 0 -#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 -#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 -#define TWSI_CTRL_SW_LDSTART 0x800 -#define TWSI_CTRL_HW_LDSTART 0x1000 -#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F -#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 -#define TWSI_CTRL_LD_EXIST 0x400000 -#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 -#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 -#define TWSI_CTRL_FREQ_SEL_100K 0 -#define TWSI_CTRL_FREQ_SEL_200K 1 -#define TWSI_CTRL_FREQ_SEL_300K 2 -#define TWSI_CTRL_FREQ_SEL_400K 3 -#define TWSI_CTRL_SMB_SLV_ADDR -#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 -#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 - -#define REG_PCIE_DEV_MISC_CTRL 0x21C -#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2 -#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1 -#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4 -#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8 -#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10 - -/* Selene Master Control Register */ -#define REG_MASTER_CTRL 0x1400 -#define MASTER_CTRL_SOFT_RST 0x1 -#define MASTER_CTRL_MTIMER_EN 0x2 -#define MASTER_CTRL_ITIMER_EN 0x4 -#define MASTER_CTRL_MANUAL_INT 0x8 -#define MASTER_CTRL_REV_NUM_SHIFT 16 -#define MASTER_CTRL_REV_NUM_MASK 0xff -#define MASTER_CTRL_DEV_ID_SHIFT 24 -#define MASTER_CTRL_DEV_ID_MASK 0xff - -/* Timer Initial Value Register */ -#define REG_MANUAL_TIMER_INIT 0x1404 - -/* IRQ ModeratorTimer Initial Value Register */ -#define REG_IRQ_MODU_TIMER_INIT 0x1408 - -#define REG_GPHY_ENABLE 0x140C - -/* IRQ Anti-Lost Timer Initial Value Register */ -#define REG_CMBDISDMA_TIMER 0x140E - -/* Block IDLE Status Register */ -#define REG_IDLE_STATUS 0x1410 -#define IDLE_STATUS_RXMAC 1 -#define IDLE_STATUS_TXMAC 2 -#define IDLE_STATUS_RXQ 4 -#define IDLE_STATUS_TXQ 8 -#define IDLE_STATUS_DMAR 0x10 -#define IDLE_STATUS_DMAW 0x20 -#define IDLE_STATUS_SMB 0x40 -#define IDLE_STATUS_CMB 0x80 - -/* MDIO Control Register */ -#define REG_MDIO_CTRL 0x1414 -#define MDIO_DATA_MASK 0xffff -#define MDIO_DATA_SHIFT 0 -#define MDIO_REG_ADDR_MASK 0x1f -#define MDIO_REG_ADDR_SHIFT 16 -#define MDIO_RW 0x200000 -#define MDIO_SUP_PREAMBLE 0x400000 -#define MDIO_START 0x800000 -#define MDIO_CLK_SEL_SHIFT 24 -#define MDIO_CLK_25_4 0 -#define MDIO_CLK_25_6 2 -#define MDIO_CLK_25_8 3 -#define MDIO_CLK_25_10 4 -#define MDIO_CLK_25_14 5 -#define MDIO_CLK_25_20 6 -#define MDIO_CLK_25_28 7 -#define MDIO_BUSY 0x8000000 -#define MDIO_WAIT_TIMES 30 - -/* MII PHY Status Register */ -#define REG_PHY_STATUS 0x1418 - -/* BIST Control and Status Register0 (for the Packet Memory) */ -#define REG_BIST0_CTRL 0x141c -#define BIST0_NOW 0x1 -#define BIST0_SRAM_FAIL 0x2 -#define BIST0_FUSE_FLAG 0x4 -#define REG_BIST1_CTRL 0x1420 -#define BIST1_NOW 0x1 -#define BIST1_SRAM_FAIL 0x2 -#define BIST1_FUSE_FLAG 0x4 - -/* MAC Control Register */ -#define REG_MAC_CTRL 0x1480 -#define MAC_CTRL_TX_EN 1 -#define MAC_CTRL_RX_EN 2 -#define MAC_CTRL_TX_FLOW 4 -#define MAC_CTRL_RX_FLOW 8 -#define MAC_CTRL_LOOPBACK 0x10 -#define MAC_CTRL_DUPLX 0x20 -#define MAC_CTRL_ADD_CRC 0x40 -#define MAC_CTRL_PAD 0x80 -#define MAC_CTRL_LENCHK 0x100 -#define MAC_CTRL_HUGE_EN 0x200 -#define MAC_CTRL_PRMLEN_SHIFT 10 -#define MAC_CTRL_PRMLEN_MASK 0xf -#define MAC_CTRL_RMV_VLAN 0x4000 -#define MAC_CTRL_PROMIS_EN 0x8000 -#define MAC_CTRL_TX_PAUSE 0x10000 -#define MAC_CTRL_SCNT 0x20000 -#define MAC_CTRL_SRST_TX 0x40000 -#define MAC_CTRL_TX_SIMURST 0x80000 -#define MAC_CTRL_SPEED_SHIFT 20 -#define MAC_CTRL_SPEED_MASK 0x300000 -#define MAC_CTRL_SPEED_1000 2 -#define MAC_CTRL_SPEED_10_100 1 -#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000 -#define MAC_CTRL_TX_HUGE 0x800000 -#define MAC_CTRL_RX_CHKSUM_EN 0x1000000 -#define MAC_CTRL_MC_ALL_EN 0x2000000 -#define MAC_CTRL_BC_EN 0x4000000 -#define MAC_CTRL_DBG 0x8000000 - -/* MAC IPG/IFG Control Register */ -#define REG_MAC_IPG_IFG 0x1484 -#define MAC_IPG_IFG_IPGT_SHIFT 0 -#define MAC_IPG_IFG_IPGT_MASK 0x7f -#define MAC_IPG_IFG_MIFG_SHIFT 8 -#define MAC_IPG_IFG_MIFG_MASK 0xff -#define MAC_IPG_IFG_IPGR1_SHIFT 16 -#define MAC_IPG_IFG_IPGR1_MASK 0x7f -#define MAC_IPG_IFG_IPGR2_SHIFT 24 -#define MAC_IPG_IFG_IPGR2_MASK 0x7f - -/* MAC STATION ADDRESS */ -#define REG_MAC_STA_ADDR 0x1488 - -/* Hash table for multicast address */ -#define REG_RX_HASH_TABLE 0x1490 - -/* MAC Half-Duplex Control Register */ -#define REG_MAC_HALF_DUPLX_CTRL 0x1498 -#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 -#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff -#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 -#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf -#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 -#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 -#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 -#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 -#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 -#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf -#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 -#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf - -/* Maximum Frame Length Control Register */ -#define REG_MTU 0x149c - -/* Wake-On-Lan control register */ -#define REG_WOL_CTRL 0x14a0 -#define WOL_PATTERN_EN 0x00000001 -#define WOL_PATTERN_PME_EN 0x00000002 -#define WOL_MAGIC_EN 0x00000004 -#define WOL_MAGIC_PME_EN 0x00000008 -#define WOL_LINK_CHG_EN 0x00000010 -#define WOL_LINK_CHG_PME_EN 0x00000020 -#define WOL_PATTERN_ST 0x00000100 -#define WOL_MAGIC_ST 0x00000200 -#define WOL_LINKCHG_ST 0x00000400 -#define WOL_CLK_SWITCH_EN 0x00008000 -#define WOL_PT0_EN 0x00010000 -#define WOL_PT1_EN 0x00020000 -#define WOL_PT2_EN 0x00040000 -#define WOL_PT3_EN 0x00080000 -#define WOL_PT4_EN 0x00100000 -#define WOL_PT5_EN 0x00200000 -#define WOL_PT6_EN 0x00400000 - -/* WOL Length ( 2 DWORD ) */ -#define REG_WOL_PATTERN_LEN 0x14a4 -#define WOL_PT_LEN_MASK 0x7f -#define WOL_PT0_LEN_SHIFT 0 -#define WOL_PT1_LEN_SHIFT 8 -#define WOL_PT2_LEN_SHIFT 16 -#define WOL_PT3_LEN_SHIFT 24 -#define WOL_PT4_LEN_SHIFT 0 -#define WOL_PT5_LEN_SHIFT 8 -#define WOL_PT6_LEN_SHIFT 16 - -/* Internal SRAM Partition Register */ -#define REG_SRAM_RFD_ADDR 0x1500 -#define REG_SRAM_RFD_LEN (REG_SRAM_RFD_ADDR+ 4) -#define REG_SRAM_RRD_ADDR (REG_SRAM_RFD_ADDR+ 8) -#define REG_SRAM_RRD_LEN (REG_SRAM_RFD_ADDR+12) -#define REG_SRAM_TPD_ADDR (REG_SRAM_RFD_ADDR+16) -#define REG_SRAM_TPD_LEN (REG_SRAM_RFD_ADDR+20) -#define REG_SRAM_TRD_ADDR (REG_SRAM_RFD_ADDR+24) -#define REG_SRAM_TRD_LEN (REG_SRAM_RFD_ADDR+28) -#define REG_SRAM_RXF_ADDR (REG_SRAM_RFD_ADDR+32) -#define REG_SRAM_RXF_LEN (REG_SRAM_RFD_ADDR+36) -#define REG_SRAM_TXF_ADDR (REG_SRAM_RFD_ADDR+40) -#define REG_SRAM_TXF_LEN (REG_SRAM_RFD_ADDR+44) -#define REG_SRAM_TCPH_PATH_ADDR (REG_SRAM_RFD_ADDR+48) -#define SRAM_TCPH_ADDR_MASK 0x0fff -#define SRAM_TCPH_ADDR_SHIFT 0 -#define SRAM_PATH_ADDR_MASK 0x0fff -#define SRAM_PATH_ADDR_SHIFT 16 - -/* Load Ptr Register */ -#define REG_LOAD_PTR (REG_SRAM_RFD_ADDR+52) - -/* Descriptor Control register */ -#define REG_DESC_BASE_ADDR_HI 0x1540 -#define REG_DESC_RFD_ADDR_LO (REG_DESC_BASE_ADDR_HI+4) -#define REG_DESC_RRD_ADDR_LO (REG_DESC_BASE_ADDR_HI+8) -#define REG_DESC_TPD_ADDR_LO (REG_DESC_BASE_ADDR_HI+12) -#define REG_DESC_CMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+16) -#define REG_DESC_SMB_ADDR_LO (REG_DESC_BASE_ADDR_HI+20) -#define REG_DESC_RFD_RRD_RING_SIZE (REG_DESC_BASE_ADDR_HI+24) -#define DESC_RFD_RING_SIZE_MASK 0x7ff -#define DESC_RFD_RING_SIZE_SHIFT 0 -#define DESC_RRD_RING_SIZE_MASK 0x7ff -#define DESC_RRD_RING_SIZE_SHIFT 16 -#define REG_DESC_TPD_RING_SIZE (REG_DESC_BASE_ADDR_HI+28) -#define DESC_TPD_RING_SIZE_MASK 0x3ff -#define DESC_TPD_RING_SIZE_SHIFT 0 - -/* TXQ Control Register */ -#define REG_TXQ_CTRL 0x1580 -#define TXQ_CTRL_TPD_BURST_NUM_SHIFT 0 -#define TXQ_CTRL_TPD_BURST_NUM_MASK 0x1f -#define TXQ_CTRL_EN 0x20 -#define TXQ_CTRL_ENH_MODE 0x40 -#define TXQ_CTRL_TPD_FETCH_TH_SHIFT 8 -#define TXQ_CTRL_TPD_FETCH_TH_MASK 0x3f -#define TXQ_CTRL_TXF_BURST_NUM_SHIFT 16 -#define TXQ_CTRL_TXF_BURST_NUM_MASK 0xffff - -/* Jumbo packet Threshold for task offload */ -#define REG_TX_JUMBO_TASK_TH_TPD_IPG 0x1584 -#define TX_JUMBO_TASK_TH_MASK 0x7ff -#define TX_JUMBO_TASK_TH_SHIFT 0 -#define TX_TPD_MIN_IPG_MASK 0x1f -#define TX_TPD_MIN_IPG_SHIFT 16 - -/* RXQ Control Register */ -#define REG_RXQ_CTRL 0x15a0 -#define RXQ_CTRL_RFD_BURST_NUM_SHIFT 0 -#define RXQ_CTRL_RFD_BURST_NUM_MASK 0xff -#define RXQ_CTRL_RRD_BURST_THRESH_SHIFT 8 -#define RXQ_CTRL_RRD_BURST_THRESH_MASK 0xff -#define RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT 16 -#define RXQ_CTRL_RFD_PREF_MIN_IPG_MASK 0x1f -#define RXQ_CTRL_CUT_THRU_EN 0x40000000 -#define RXQ_CTRL_EN 0x80000000 - -/* Rx jumbo packet threshold and rrd retirement timer */ -#define REG_RXQ_JMBOSZ_RRDTIM (REG_RXQ_CTRL+ 4) -#define RXQ_JMBOSZ_TH_MASK 0x7ff -#define RXQ_JMBOSZ_TH_SHIFT 0 -#define RXQ_JMBO_LKAH_MASK 0xf -#define RXQ_JMBO_LKAH_SHIFT 11 -#define RXQ_RRD_TIMER_MASK 0xffff -#define RXQ_RRD_TIMER_SHIFT 16 - -/* RFD flow control register */ -#define REG_RXQ_RXF_PAUSE_THRESH (REG_RXQ_CTRL+ 8) -#define RXQ_RXF_PAUSE_TH_HI_SHIFT 16 -#define RXQ_RXF_PAUSE_TH_HI_MASK 0xfff -#define RXQ_RXF_PAUSE_TH_LO_SHIFT 0 -#define RXQ_RXF_PAUSE_TH_LO_MASK 0xfff - -/* RRD flow control register */ -#define REG_RXQ_RRD_PAUSE_THRESH (REG_RXQ_CTRL+12) -#define RXQ_RRD_PAUSE_TH_HI_SHIFT 0 -#define RXQ_RRD_PAUSE_TH_HI_MASK 0xfff -#define RXQ_RRD_PAUSE_TH_LO_SHIFT 16 -#define RXQ_RRD_PAUSE_TH_LO_MASK 0xfff - -/* DMA Engine Control Register */ -#define REG_DMA_CTRL 0x15c0 -#define DMA_CTRL_DMAR_IN_ORDER 0x1 -#define DMA_CTRL_DMAR_ENH_ORDER 0x2 -#define DMA_CTRL_DMAR_OUT_ORDER 0x4 -#define DMA_CTRL_RCB_VALUE 0x8 -#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4 -#define DMA_CTRL_DMAR_BURST_LEN_MASK 7 -#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7 -#define DMA_CTRL_DMAW_BURST_LEN_MASK 7 -#define DMA_CTRL_DMAR_EN 0x400 -#define DMA_CTRL_DMAW_EN 0x800 - -/* CMB/SMB Control Register */ -#define REG_CSMB_CTRL 0x15d0 -#define CSMB_CTRL_CMB_NOW 1 -#define CSMB_CTRL_SMB_NOW 2 -#define CSMB_CTRL_CMB_EN 4 -#define CSMB_CTRL_SMB_EN 8 - -/* CMB DMA Write Threshold Register */ -#define REG_CMB_WRITE_TH (REG_CSMB_CTRL+ 4) -#define CMB_RRD_TH_SHIFT 0 -#define CMB_RRD_TH_MASK 0x7ff -#define CMB_TPD_TH_SHIFT 16 -#define CMB_TPD_TH_MASK 0x7ff - -/* RX/TX count-down timer to trigger CMB-write. 2us resolution. */ -#define REG_CMB_WRITE_TIMER (REG_CSMB_CTRL+ 8) -#define CMB_RX_TM_SHIFT 0 -#define CMB_RX_TM_MASK 0xffff -#define CMB_TX_TM_SHIFT 16 -#define CMB_TX_TM_MASK 0xffff - -/* Number of packet received since last CMB write */ -#define REG_CMB_RX_PKT_CNT (REG_CSMB_CTRL+12) - -/* Number of packet transmitted since last CMB write */ -#define REG_CMB_TX_PKT_CNT (REG_CSMB_CTRL+16) - -/* SMB auto DMA timer register */ -#define REG_SMB_TIMER (REG_CSMB_CTRL+20) - -/* Mailbox Register */ -#define REG_MAILBOX 0x15f0 -#define MB_RFD_PROD_INDX_SHIFT 0 -#define MB_RFD_PROD_INDX_MASK 0x7ff -#define MB_RRD_CONS_INDX_SHIFT 11 -#define MB_RRD_CONS_INDX_MASK 0x7ff -#define MB_TPD_PROD_INDX_SHIFT 22 -#define MB_TPD_PROD_INDX_MASK 0x3ff - -/* Interrupt Status Register */ -#define REG_ISR 0x1600 -#define ISR_SMB 1 -#define ISR_TIMER 2 -#define ISR_MANUAL 4 -#define ISR_RXF_OV 8 -#define ISR_RFD_UNRUN 0x10 -#define ISR_RRD_OV 0x20 -#define ISR_TXF_UNRUN 0x40 -#define ISR_LINK 0x80 -#define ISR_HOST_RFD_UNRUN 0x100 -#define ISR_HOST_RRD_OV 0x200 -#define ISR_DMAR_TO_RST 0x400 -#define ISR_DMAW_TO_RST 0x800 -#define ISR_GPHY 0x1000 -#define ISR_RX_PKT 0x10000 -#define ISR_TX_PKT 0x20000 -#define ISR_TX_DMA 0x40000 -#define ISR_RX_DMA 0x80000 -#define ISR_CMB_RX 0x100000 -#define ISR_CMB_TX 0x200000 -#define ISR_MAC_RX 0x400000 -#define ISR_MAC_TX 0x800000 -#define ISR_UR_DETECTED 0x1000000 -#define ISR_FERR_DETECTED 0x2000000 -#define ISR_NFERR_DETECTED 0x4000000 -#define ISR_CERR_DETECTED 0x8000000 -#define ISR_PHY_LINKDOWN 0x10000000 -#define ISR_DIS_SMB 0x20000000 -#define ISR_DIS_DMA 0x40000000 -#define ISR_DIS_INT 0x80000000 - -/* Interrupt Mask Register */ -#define REG_IMR 0x1604 - -/* Normal Interrupt mask */ -#define IMR_NORMAL_MASK (\ - ISR_SMB |\ - ISR_GPHY |\ - ISR_PHY_LINKDOWN|\ - ISR_DMAR_TO_RST |\ - ISR_DMAW_TO_RST |\ - ISR_CMB_TX |\ - ISR_CMB_RX ) - -/* Debug Interrupt Mask (enable all interrupt) */ -#define IMR_DEBUG_MASK (\ - ISR_SMB |\ - ISR_TIMER |\ - ISR_MANUAL |\ - ISR_RXF_OV |\ - ISR_RFD_UNRUN |\ - ISR_RRD_OV |\ - ISR_TXF_UNRUN |\ - ISR_LINK |\ - ISR_CMB_TX |\ - ISR_CMB_RX |\ - ISR_RX_PKT |\ - ISR_TX_PKT |\ - ISR_MAC_RX |\ - ISR_MAC_TX ) - -/* Interrupt Status Register */ -#define REG_RFD_RRD_IDX 0x1800 -#define REG_TPD_IDX 0x1804 - -/* MII definition */ -/* PHY Common Register */ -#define MII_AT001_CR 0x09 -#define MII_AT001_SR 0x0A -#define MII_AT001_ESR 0x0F -#define MII_AT001_PSCR 0x10 -#define MII_AT001_PSSR 0x11 - -/* PHY Control Register */ -#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ -#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define MII_CR_SPEED_MASK 0x2040 -#define MII_CR_SPEED_1000 0x0040 -#define MII_CR_SPEED_100 0x2000 -#define MII_CR_SPEED_10 0x0000 - -/* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ - -/* Link partner ability register. */ -#define MII_LPA_SLCT 0x001f /* Same as advertise selector */ -#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ -#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ -#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ -#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ -#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */ -#define MII_LPA_PAUSE 0x0400 /* PAUSE */ -#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */ -#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */ -#define MII_LPA_LPACK 0x4000 /* Link partner acked us */ -#define MII_LPA_NPAGE 0x8000 /* Next page bit */ - -/* Autoneg Advertisement Register */ -#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ -#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ -#define MII_AR_PAUSE 0x0400 /* Pause operation desired */ -#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ -#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ -#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ -#define MII_AR_SPEED_MASK 0x01E0 -#define MII_AR_DEFAULT_CAP_MASK 0x0DE0 - -/* 1000BASE-T Control Register */ -#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ -#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ -#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port, 0=DTE device */ -#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master, 0=Configure PHY as Slave */ -#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value, 0=Automatic Master/Slave config */ -#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ -#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ -#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ -#define MII_AT001_CR_1000T_SPEED_MASK 0x0300 -#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300 - -/* 1000BASE-T Status Register */ -#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ -#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ -#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ -#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12 -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13 - -/* Extended Status Register */ -#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ -#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ -#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ -#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ - -/* AT001 PHY Specific Control Register */ -#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ -#define MII_AT001_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ -#define MII_AT001_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ -#define MII_AT001_PSCR_MAC_POWERDOWN 0x0008 -#define MII_AT001_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, 0=CLK125 toggling */ -#define MII_AT001_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5, Manual MDI configuration */ -#define MII_AT001_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ -#define MII_AT001_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ -#define MII_AT001_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled all speeds. */ -#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold), 0=Normal 10BASE-T RX Threshold */ -#define MII_AT001_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ -#define MII_AT001_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ -#define MII_AT001_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ -#define MII_AT001_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ -#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT 1 -#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT 5 -#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 - -/* AT001 PHY Specific Status Register */ -#define MII_AT001_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ -#define MII_AT001_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ -#define MII_AT001_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ -#define MII_AT001_PSSR_10MBS 0x0000 /* 00=10Mbs */ -#define MII_AT001_PSSR_100MBS 0x4000 /* 01=100Mbs */ -#define MII_AT001_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ - -/* PCI Command Register Bit Definitions */ -#define PCI_REG_COMMAND 0x04 /* PCI Command Register */ -#define CMD_IO_SPACE 0x0001 -#define CMD_MEMORY_SPACE 0x0002 -#define CMD_BUS_MASTER 0x0004 - -/* Wake Up Filter Control */ -#define ATL1_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -#define ATL1_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ -#define ATL1_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ -#define ATL1_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ -#define ATL1_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ - -/* Error Codes */ -#define ATL1_SUCCESS 0 -#define ATL1_ERR_EEPROM 1 -#define ATL1_ERR_PHY 2 -#define ATL1_ERR_CONFIG 3 -#define ATL1_ERR_PARAM 4 -#define ATL1_ERR_MAC_TYPE 5 -#define ATL1_ERR_PHY_TYPE 6 -#define ATL1_ERR_PHY_SPEED 7 -#define ATL1_ERR_PHY_RES 8 - -#define SPEED_0 0xffff -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 - -#define MEDIA_TYPE_AUTO_SENSOR 0 -#define MEDIA_TYPE_1000M_FULL 1 -#define MEDIA_TYPE_100M_FULL 2 -#define MEDIA_TYPE_100M_HALF 3 -#define MEDIA_TYPE_10M_FULL 4 -#define MEDIA_TYPE_10M_HALF 5 - -#define ADVERTISE_10_HALF 0x0001 -#define ADVERTISE_10_FULL 0x0002 -#define ADVERTISE_100_HALF 0x0004 -#define ADVERTISE_100_FULL 0x0008 -#define ADVERTISE_1000_HALF 0x0010 -#define ADVERTISE_1000_FULL 0x0020 -#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */ -#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */ -#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */ - -/* The size (in bytes) of a ethernet packet */ -#define ENET_HEADER_SIZE 14 -#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */ -#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */ -#define ETHERNET_FCS_SIZE 4 -#define MAX_JUMBO_FRAME_SIZE 0x2800 - -#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */ -#define PHY_FORCE_TIME 20 /* 2.0 Seconds */ - -/* For checksumming , the sum of all words in the EEPROM should equal 0xBABA */ -#define EEPROM_SUM 0xBABA - -#define ATL1_EEDUMP_LEN 48 - -/* Statistics counters collected by the MAC */ -struct stats_msg_block { - /* rx */ - u32 rx_ok; /* The number of good packet received. */ - u32 rx_bcast; /* The number of good broadcast packet received. */ - u32 rx_mcast; /* The number of good multicast packet received. */ - u32 rx_pause; /* The number of Pause packet received. */ - u32 rx_ctrl; /* The number of Control packet received other than Pause frame. */ - u32 rx_fcs_err; /* The number of packets with bad FCS. */ - u32 rx_len_err; /* The number of packets with mismatch of length field and actual size. */ - u32 rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */ - u32 rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */ - u32 rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */ - u32 rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */ - u32 rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */ - u32 rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */ - u32 rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */ - u32 rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */ - u32 rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */ - u32 rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */ - u32 rx_sz_ov; /* The number of good and bad packets received that are more than MTU size Å¡C truncated by Selene. */ - u32 rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */ - u32 rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */ - u32 rx_align_err; /* Alignment Error */ - u32 rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */ - u32 rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */ - u32 rx_err_addr; /* The number of packets dropped due to address filtering. */ - - /* tx */ - u32 tx_ok; /* The number of good packet transmitted. */ - u32 tx_bcast; /* The number of good broadcast packet transmitted. */ - u32 tx_mcast; /* The number of good multicast packet transmitted. */ - u32 tx_pause; /* The number of Pause packet transmitted. */ - u32 tx_exc_defer; /* The number of packets transmitted with excessive deferral. */ - u32 tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */ - u32 tx_defer; /* The number of packets transmitted that is deferred. */ - u32 tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */ - u32 tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */ - u32 tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */ - u32 tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */ - u32 tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */ - u32 tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */ - u32 tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */ - u32 tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */ - u32 tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */ - u32 tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */ - u32 tx_late_col; /* The number of packets transmitted with late collisions. */ - u32 tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */ - u32 tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */ - u32 tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */ - u32 tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */ - u32 tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */ - u32 tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */ - u32 tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */ - u32 smb_updated; /* 1: SMB Updated. This is used by software as the indication of the statistics update. - * Software should clear this bit as soon as retrieving the statistics information. */ -}; - -/* Coalescing Message Block */ -struct coals_msg_block { - u32 int_stats; /* interrupt status */ - u16 rrd_prod_idx; /* TRD Producer Index. */ - u16 rfd_cons_idx; /* RFD Consumer Index. */ - u16 update; /* Selene sets this bit every time it DMA the CMB to host memory. - * Software supposes to clear this bit when CMB information is processed. */ - u16 tpd_cons_idx; /* TPD Consumer Index. */ -}; - -/* RRD descriptor */ -struct rx_return_desc { - u8 num_buf; /* Number of RFD buffers used by the received packet */ - u8 resved; - u16 buf_indx; /* RFD Index of the first buffer */ - union { - u32 valid; - struct { - u16 rx_chksum; - u16 pkt_size; - } xsum_sz; - } xsz; - - u16 pkt_flg; /* Packet flags */ - u16 err_flg; /* Error flags */ - u16 resved2; - u16 vlan_tag; /* VLAN TAG */ -}; - -#define PACKET_FLAG_ETH_TYPE 0x0080 -#define PACKET_FLAG_VLAN_INS 0x0100 -#define PACKET_FLAG_ERR 0x0200 -#define PACKET_FLAG_IPV4 0x0400 -#define PACKET_FLAG_UDP 0x0800 -#define PACKET_FLAG_TCP 0x1000 -#define PACKET_FLAG_BCAST 0x2000 -#define PACKET_FLAG_MCAST 0x4000 -#define PACKET_FLAG_PAUSE 0x8000 - -#define ERR_FLAG_CRC 0x0001 -#define ERR_FLAG_CODE 0x0002 -#define ERR_FLAG_DRIBBLE 0x0004 -#define ERR_FLAG_RUNT 0x0008 -#define ERR_FLAG_OV 0x0010 -#define ERR_FLAG_TRUNC 0x0020 -#define ERR_FLAG_IP_CHKSUM 0x0040 -#define ERR_FLAG_L4_CHKSUM 0x0080 -#define ERR_FLAG_LEN 0x0100 -#define ERR_FLAG_DES_ADDR 0x0200 - -/* RFD descriptor */ -struct rx_free_desc { - __le64 buffer_addr; /* Address of the descriptor's data buffer */ - __le16 buf_len; /* Size of the receive buffer in host memory, in byte */ - u16 coalese; /* Update consumer index to host after the reception of this frame */ - /* __attribute__ ((packed)) is required */ -} __attribute__ ((packed)); - -/* tsopu defines */ -#define TSO_PARAM_BUFLEN_MASK 0x3FFF -#define TSO_PARAM_BUFLEN_SHIFT 0 -#define TSO_PARAM_DMAINT_MASK 0x0001 -#define TSO_PARAM_DMAINT_SHIFT 14 -#define TSO_PARAM_PKTNT_MASK 0x0001 -#define TSO_PARAM_PKTINT_SHIFT 15 -#define TSO_PARAM_VLANTAG_MASK 0xFFFF -#define TSO_PARAM_VLAN_SHIFT 16 - -/* tsopl defines */ -#define TSO_PARAM_EOP_MASK 0x0001 -#define TSO_PARAM_EOP_SHIFT 0 -#define TSO_PARAM_COALESCE_MASK 0x0001 -#define TSO_PARAM_COALESCE_SHIFT 1 -#define TSO_PARAM_INSVLAG_MASK 0x0001 -#define TSO_PARAM_INSVLAG_SHIFT 2 -#define TSO_PARAM_CUSTOMCKSUM_MASK 0x0001 -#define TSO_PARAM_CUSTOMCKSUM_SHIFT 3 -#define TSO_PARAM_SEGMENT_MASK 0x0001 -#define TSO_PARAM_SEGMENT_SHIFT 4 -#define TSO_PARAM_IPCKSUM_MASK 0x0001 -#define TSO_PARAM_IPCKSUM_SHIFT 5 -#define TSO_PARAM_TCPCKSUM_MASK 0x0001 -#define TSO_PARAM_TCPCKSUM_SHIFT 6 -#define TSO_PARAM_UDPCKSUM_MASK 0x0001 -#define TSO_PARAM_UDPCKSUM_SHIFT 7 -#define TSO_PARAM_VLANTAGGED_MASK 0x0001 -#define TSO_PARAM_VLANTAGGED_SHIFT 8 -#define TSO_PARAM_ETHTYPE_MASK 0x0001 -#define TSO_PARAM_ETHTYPE_SHIFT 9 -#define TSO_PARAM_IPHL_MASK 0x000F -#define TSO_PARAM_IPHL_SHIFT 10 -#define TSO_PARAM_TCPHDRLEN_MASK 0x000F -#define TSO_PARAM_TCPHDRLEN_SHIFT 14 -#define TSO_PARAM_HDRFLAG_MASK 0x0001 -#define TSO_PARAM_HDRFLAG_SHIFT 18 -#define TSO_PARAM_MSS_MASK 0x1FFF -#define TSO_PARAM_MSS_SHIFT 19 - -/* csumpu defines */ -#define CSUM_PARAM_BUFLEN_MASK 0x3FFF -#define CSUM_PARAM_BUFLEN_SHIFT 0 -#define CSUM_PARAM_DMAINT_MASK 0x0001 -#define CSUM_PARAM_DMAINT_SHIFT 14 -#define CSUM_PARAM_PKTINT_MASK 0x0001 -#define CSUM_PARAM_PKTINT_SHIFT 15 -#define CSUM_PARAM_VALANTAG_MASK 0xFFFF -#define CSUM_PARAM_VALAN_SHIFT 16 - -/* csumpl defines*/ -#define CSUM_PARAM_EOP_MASK 0x0001 -#define CSUM_PARAM_EOP_SHIFT 0 -#define CSUM_PARAM_COALESCE_MASK 0x0001 -#define CSUM_PARAM_COALESCE_SHIFT 1 -#define CSUM_PARAM_INSVLAG_MASK 0x0001 -#define CSUM_PARAM_INSVLAG_SHIFT 2 -#define CSUM_PARAM_CUSTOMCKSUM_MASK 0x0001 -#define CSUM_PARAM_CUSTOMCKSUM_SHIFT 3 -#define CSUM_PARAM_SEGMENT_MASK 0x0001 -#define CSUM_PARAM_SEGMENT_SHIFT 4 -#define CSUM_PARAM_IPCKSUM_MASK 0x0001 -#define CSUM_PARAM_IPCKSUM_SHIFT 5 -#define CSUM_PARAM_TCPCKSUM_MASK 0x0001 -#define CSUM_PARAM_TCPCKSUM_SHIFT 6 -#define CSUM_PARAM_UDPCKSUM_MASK 0x0001 -#define CSUM_PARAM_UDPCKSUM_SHIFT 7 -#define CSUM_PARAM_VLANTAGGED_MASK 0x0001 -#define CSUM_PARAM_VLANTAGGED_SHIFT 8 -#define CSUM_PARAM_ETHTYPE_MASK 0x0001 -#define CSUM_PARAM_ETHTYPE_SHIFT 9 -#define CSUM_PARAM_IPHL_MASK 0x000F -#define CSUM_PARAM_IPHL_SHIFT 10 -#define CSUM_PARAM_PLOADOFFSET_MASK 0x00FF -#define CSUM_PARAM_PLOADOFFSET_SHIFT 16 -#define CSUM_PARAM_XSUMOFFSET_MASK 0x00FF -#define CSUM_PARAM_XSUMOFFSET_SHIFT 24 - -/* TPD descriptor */ -struct tso_param { - /* The order of these declarations is important -- don't change it */ - u32 tsopu; /* tso_param upper word */ - u32 tsopl; /* tso_param lower word */ -}; - -struct csum_param { - /* The order of these declarations is important -- don't change it */ - u32 csumpu; /* csum_param upper word */ - u32 csumpl; /* csum_param lower word */ -}; - -union tpd_descr { - u64 data; - struct csum_param csum; - struct tso_param tso; -}; - -struct tx_packet_desc { - __le64 buffer_addr; - union tpd_descr desc; -}; - -/* DMA Order Settings */ -enum atl1_dma_order { - atl1_dma_ord_in = 1, - atl1_dma_ord_enh = 2, - atl1_dma_ord_out = 4 -}; - -enum atl1_dma_rcb { - atl1_rcb_64 = 0, - atl1_rcb_128 = 1 -}; - -enum atl1_dma_req_block { - atl1_dma_req_128 = 0, - atl1_dma_req_256 = 1, - atl1_dma_req_512 = 2, - atl1_dam_req_1024 = 3, - atl1_dam_req_2048 = 4, - atl1_dma_req_4096 = 5 -}; - -struct atl1_spi_flash_dev { - const char *manu_name; /* manufacturer id */ - /* op-code */ - u8 cmd_wrsr; - u8 cmd_read; - u8 cmd_program; - u8 cmd_wren; - u8 cmd_wrdi; - u8 cmd_rdsr; - u8 cmd_rdid; - u8 cmd_sector_erase; - u8 cmd_chip_erase; -}; - -#endif /* _ATL1_HW_H_ */ diff --git a/trunk/drivers/net/atl1/atl1_main.c b/trunk/drivers/net/atl1/atl1_main.c deleted file mode 100644 index 6655640eb4ca..000000000000 --- a/trunk/drivers/net/atl1/atl1_main.c +++ /dev/null @@ -1,2468 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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. - * - * The full GNU General Public License is included in this distribution in the - * file called COPYING. - * - * Contact Information: - * Xiong Huang - * Attansic Technology Corp. 3F 147, Xianzheng 9th Road, Zhubei, - * Xinzhu 302, TAIWAN, REPUBLIC OF CHINA - * - * Chris Snook - * Jay Cliburn - * - * This version is adapted from the Attansic reference driver for - * inclusion in the Linux kernel. It is currently under heavy development. - * A very incomplete list of things that need to be dealt with: - * - * TODO: - * Fix TSO; tx performance is horrible with TSO enabled. - * Wake on LAN. - * Add more ethtool functions, including set ring parameters. - * Fix abstruse irq enable/disable condition described here: - * http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2 - * - * NEEDS TESTING: - * VLAN - * multicast - * promiscuous mode - * interrupt coalescing - * SMP torture testing - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "atl1.h" - -#define RUN_REALTIME 0 -#define DRIVER_VERSION "2.0.6" - -char atl1_driver_name[] = "atl1"; -static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver"; -static const char atl1_copyright[] = "Copyright(c) 2005-2006 Attansic Corporation."; -char atl1_driver_version[] = DRIVER_VERSION; - -MODULE_AUTHOR - ("Attansic Corporation , Chris Snook , Jay Cliburn "); -MODULE_DESCRIPTION("Attansic 1000M Ethernet Network Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - -/* - * atl1_pci_tbl - PCI Device ID Table - */ -static const struct pci_device_id atl1_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1048)}, - /* required last entry */ - {0,} -}; - -MODULE_DEVICE_TABLE(pci, atl1_pci_tbl); - -/* - * atl1_sw_init - Initialize general software structures (struct atl1_adapter) - * @adapter: board private structure to initialize - * - * atl1_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). - */ -static int __devinit atl1_sw_init(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* PCI config space info */ - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); - - hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; - - adapter->wol = 0; - adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; - adapter->ict = 50000; /* 100ms */ - adapter->link_speed = SPEED_0; /* hardware init */ - adapter->link_duplex = FULL_DUPLEX; - - hw->phy_configured = false; - hw->preamble_len = 7; - hw->ipgt = 0x60; - hw->min_ifg = 0x50; - hw->ipgr1 = 0x40; - hw->ipgr2 = 0x60; - hw->max_retry = 0xf; - hw->lcol = 0x37; - hw->jam_ipg = 7; - hw->rfd_burst = 8; - hw->rrd_burst = 8; - hw->rfd_fetch_gap = 1; - hw->rx_jumbo_th = adapter->rx_buffer_len / 8; - hw->rx_jumbo_lkah = 1; - hw->rrd_ret_timer = 16; - hw->tpd_burst = 4; - hw->tpd_fetch_th = 16; - hw->txf_burst = 0x100; - hw->tx_jumbo_task_th = (hw->max_frame_size + 7) >> 3; - hw->tpd_fetch_gap = 1; - hw->rcb_value = atl1_rcb_64; - hw->dma_ord = atl1_dma_ord_enh; - hw->dmar_block = atl1_dma_req_256; - hw->dmaw_block = atl1_dma_req_256; - hw->cmb_rrd = 4; - hw->cmb_tpd = 4; - hw->cmb_rx_timer = 1; /* about 2us */ - hw->cmb_tx_timer = 1; /* about 2us */ - hw->smb_timer = 100000; /* about 200ms */ - - atomic_set(&adapter->irq_sem, 0); - spin_lock_init(&adapter->lock); - spin_lock_init(&adapter->mb_lock); - - return 0; -} - -/* - * atl1_setup_mem_resources - allocate Tx / RX descriptor resources - * @adapter: board private structure - * - * Return 0 on success, negative on failure - */ -s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_ring_header *ring_header = &adapter->ring_header; - struct pci_dev *pdev = adapter->pdev; - int size; - u8 offset = 0; - - size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count); - tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); - if (unlikely(!tpd_ring->buffer_info)) { - printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n", - atl1_driver_name, size); - goto err_nomem; - } - rfd_ring->buffer_info = - (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count); - - /* real ring DMA buffer */ - ring_header->size = size = sizeof(struct tx_packet_desc) * - tpd_ring->count - + sizeof(struct rx_free_desc) * rfd_ring->count - + sizeof(struct rx_return_desc) * rrd_ring->count - + sizeof(struct coals_msg_block) - + sizeof(struct stats_msg_block) - + 40; /* "40: for 8 bytes align" huh? -- CHS */ - - ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, - &ring_header->dma); - if (unlikely(!ring_header->desc)) { - printk(KERN_WARNING - "%s: pci_alloc_consistent failed, size = D%d\n", - atl1_driver_name, size); - goto err_nomem; - } - - memset(ring_header->desc, 0, ring_header->size); - - /* init TPD ring */ - tpd_ring->dma = ring_header->dma; - offset = (tpd_ring->dma & 0x7) ? (8 - (ring_header->dma & 0x7)) : 0; - tpd_ring->dma += offset; - tpd_ring->desc = (u8 *) ring_header->desc + offset; - tpd_ring->size = sizeof(struct tx_packet_desc) * tpd_ring->count; - atomic_set(&tpd_ring->next_to_use, 0); - atomic_set(&tpd_ring->next_to_clean, 0); - - /* init RFD ring */ - rfd_ring->dma = tpd_ring->dma + tpd_ring->size; - offset = (rfd_ring->dma & 0x7) ? (8 - (rfd_ring->dma & 0x7)) : 0; - rfd_ring->dma += offset; - rfd_ring->desc = (u8 *) tpd_ring->desc + (tpd_ring->size + offset); - rfd_ring->size = sizeof(struct rx_free_desc) * rfd_ring->count; - rfd_ring->next_to_clean = 0; - /* rfd_ring->next_to_use = rfd_ring->count - 1; */ - atomic_set(&rfd_ring->next_to_use, 0); - - /* init RRD ring */ - rrd_ring->dma = rfd_ring->dma + rfd_ring->size; - offset = (rrd_ring->dma & 0x7) ? (8 - (rrd_ring->dma & 0x7)) : 0; - rrd_ring->dma += offset; - rrd_ring->desc = (u8 *) rfd_ring->desc + (rfd_ring->size + offset); - rrd_ring->size = sizeof(struct rx_return_desc) * rrd_ring->count; - rrd_ring->next_to_use = 0; - atomic_set(&rrd_ring->next_to_clean, 0); - - /* init CMB */ - adapter->cmb.dma = rrd_ring->dma + rrd_ring->size; - offset = (adapter->cmb.dma & 0x7) ? (8 - (adapter->cmb.dma & 0x7)) : 0; - adapter->cmb.dma += offset; - adapter->cmb.cmb = - (struct coals_msg_block *) ((u8 *) rrd_ring->desc + - (rrd_ring->size + offset)); - - /* init SMB */ - adapter->smb.dma = adapter->cmb.dma + sizeof(struct coals_msg_block); - offset = (adapter->smb.dma & 0x7) ? (8 - (adapter->smb.dma & 0x7)) : 0; - adapter->smb.dma += offset; - adapter->smb.smb = (struct stats_msg_block *) - ((u8 *) adapter->cmb.cmb + (sizeof(struct coals_msg_block) + offset)); - - return ATL1_SUCCESS; - -err_nomem: - kfree(tpd_ring->buffer_info); - return -ENOMEM; -} - -/* - * atl1_irq_enable - Enable default interrupt generation settings - * @adapter: board private structure - */ -static void atl1_irq_enable(struct atl1_adapter *adapter) -{ - if (likely(!atomic_dec_and_test(&adapter->irq_sem))) - iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR); -} - -static void atl1_clear_phy_int(struct atl1_adapter *adapter) -{ - u16 phy_data; - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - atl1_read_phy_reg(&adapter->hw, 19, &phy_data); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -static void atl1_inc_smb(struct atl1_adapter *adapter) -{ - struct stats_msg_block *smb = adapter->smb.smb; - - /* Fill out the OS statistics structure */ - adapter->soft_stats.rx_packets += smb->rx_ok; - adapter->soft_stats.tx_packets += smb->tx_ok; - adapter->soft_stats.rx_bytes += smb->rx_byte_cnt; - adapter->soft_stats.tx_bytes += smb->tx_byte_cnt; - adapter->soft_stats.multicast += smb->rx_mcast; - adapter->soft_stats.collisions += (smb->tx_1_col + - smb->tx_2_col * 2 + - smb->tx_late_col + - smb->tx_abort_col * - adapter->hw.max_retry); - - /* Rx Errors */ - adapter->soft_stats.rx_errors += (smb->rx_frag + - smb->rx_fcs_err + - smb->rx_len_err + - smb->rx_sz_ov + - smb->rx_rxf_ov + - smb->rx_rrd_ov + smb->rx_align_err); - adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov; - adapter->soft_stats.rx_length_errors += smb->rx_len_err; - adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err; - adapter->soft_stats.rx_frame_errors += smb->rx_align_err; - adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov + - smb->rx_rxf_ov); - - adapter->soft_stats.rx_pause += smb->rx_pause; - adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov; - adapter->soft_stats.rx_trunc += smb->rx_sz_ov; - - /* Tx Errors */ - adapter->soft_stats.tx_errors += (smb->tx_late_col + - smb->tx_abort_col + - smb->tx_underrun + smb->tx_trunc); - adapter->soft_stats.tx_fifo_errors += smb->tx_underrun; - adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col; - adapter->soft_stats.tx_window_errors += smb->tx_late_col; - - adapter->soft_stats.excecol += smb->tx_abort_col; - adapter->soft_stats.deffer += smb->tx_defer; - adapter->soft_stats.scc += smb->tx_1_col; - adapter->soft_stats.mcc += smb->tx_2_col; - adapter->soft_stats.latecol += smb->tx_late_col; - adapter->soft_stats.tx_underun += smb->tx_underrun; - adapter->soft_stats.tx_trunc += smb->tx_trunc; - adapter->soft_stats.tx_pause += smb->tx_pause; - - adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets; - adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets; - adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes; - adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes; - adapter->net_stats.multicast = adapter->soft_stats.multicast; - adapter->net_stats.collisions = adapter->soft_stats.collisions; - adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors; - adapter->net_stats.rx_over_errors = - adapter->soft_stats.rx_missed_errors; - adapter->net_stats.rx_length_errors = - adapter->soft_stats.rx_length_errors; - adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors; - adapter->net_stats.rx_frame_errors = - adapter->soft_stats.rx_frame_errors; - adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors; - adapter->net_stats.rx_missed_errors = - adapter->soft_stats.rx_missed_errors; - adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors; - adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors; - adapter->net_stats.tx_aborted_errors = - adapter->soft_stats.tx_aborted_errors; - adapter->net_stats.tx_window_errors = - adapter->soft_stats.tx_window_errors; - adapter->net_stats.tx_carrier_errors = - adapter->soft_stats.tx_carrier_errors; -} - -static void atl1_rx_checksum(struct atl1_adapter *adapter, - struct rx_return_desc *rrd, - struct sk_buff *skb) -{ - skb->ip_summed = CHECKSUM_NONE; - - if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { - if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | - ERR_FLAG_CODE | ERR_FLAG_OV)) { - adapter->hw_csum_err++; - printk(KERN_DEBUG "%s: rx checksum error\n", - atl1_driver_name); - return; - } - } - - /* not IPv4 */ - if (!(rrd->pkt_flg & PACKET_FLAG_IPV4)) - /* checksum is invalid, but it's not an IPv4 pkt, so ok */ - return; - - /* IPv4 packet */ - if (likely(!(rrd->err_flg & - (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - adapter->hw_csum_good++; - return; - } - - /* IPv4, but hardware thinks its checksum is wrong */ - printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n", - atl1_driver_name, rrd->pkt_flg, rrd->err_flg); - skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); - adapter->hw_csum_err++; - return; -} - -/* - * atl1_alloc_rx_buffers - Replace used receive buffers - * @adapter: address of board private structure - */ -static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter) -{ - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct page *page; - unsigned long offset; - struct atl1_buffer *buffer_info, *next_info; - struct sk_buff *skb; - u16 num_alloc = 0; - u16 rfd_next_to_use, next_next; - struct rx_free_desc *rfd_desc; - - next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use); - if (++next_next == rfd_ring->count) - next_next = 0; - buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; - next_info = &rfd_ring->buffer_info[next_next]; - - while (!buffer_info->alloced && !next_info->alloced) { - if (buffer_info->skb) { - buffer_info->alloced = 1; - goto next; - } - - rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use); - - skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); - if (unlikely(!skb)) { /* Better luck next round */ - adapter->net_stats.rx_dropped++; - break; - } - - /* - * Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after - * the 14 byte MAC header is removed - */ - skb_reserve(skb, NET_IP_ALIGN); - skb->dev = netdev; - - buffer_info->alloced = 1; - buffer_info->skb = skb; - buffer_info->length = (u16) adapter->rx_buffer_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(pdev, page, offset, - adapter->rx_buffer_len, - PCI_DMA_FROMDEVICE); - rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); - rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len); - rfd_desc->coalese = 0; - -next: - rfd_next_to_use = next_next; - if (unlikely(++next_next == rfd_ring->count)) - next_next = 0; - - buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; - next_info = &rfd_ring->buffer_info[next_next]; - num_alloc++; - } - - if (num_alloc) { - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use); - } - return num_alloc; -} - -static void atl1_intr_rx(struct atl1_adapter *adapter) -{ - int i, count; - u16 length; - u16 rrd_next_to_clean; - u32 value; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_buffer *buffer_info; - struct rx_return_desc *rrd; - struct sk_buff *skb; - - count = 0; - - rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean); - - while (1) { - rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean); - i = 1; - if (likely(rrd->xsz.valid)) { /* packet valid */ -chk_rrd: - /* check rrd status */ - if (likely(rrd->num_buf == 1)) - goto rrd_ok; - - /* rrd seems to be bad */ - if (unlikely(i-- > 0)) { - /* rrd may not be DMAed completely */ - printk(KERN_DEBUG - "%s: RRD may not be DMAed completely\n", - atl1_driver_name); - udelay(1); - goto chk_rrd; - } - /* bad rrd */ - printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name); - /* see if update RFD index */ - if (rrd->num_buf > 1) { - u16 num_buf; - num_buf = - (rrd->xsz.xsum_sz.pkt_size + - adapter->rx_buffer_len - - 1) / adapter->rx_buffer_len; - if (rrd->num_buf == num_buf) { - /* clean alloc flag for bad rrd */ - while (rfd_ring->next_to_clean != - (rrd->buf_indx + num_buf)) { - rfd_ring->buffer_info[rfd_ring-> - next_to_clean].alloced = 0; - if (++rfd_ring->next_to_clean == - rfd_ring->count) { - rfd_ring-> - next_to_clean = 0; - } - } - } - } - - /* update rrd */ - rrd->xsz.valid = 0; - if (++rrd_next_to_clean == rrd_ring->count) - rrd_next_to_clean = 0; - count++; - continue; - } else { /* current rrd still not be updated */ - - break; - } -rrd_ok: - /* clean alloc flag for bad rrd */ - while (rfd_ring->next_to_clean != rrd->buf_indx) { - rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = - 0; - if (++rfd_ring->next_to_clean == rfd_ring->count) - rfd_ring->next_to_clean = 0; - } - - buffer_info = &rfd_ring->buffer_info[rrd->buf_indx]; - if (++rfd_ring->next_to_clean == rfd_ring->count) - rfd_ring->next_to_clean = 0; - - /* update rrd next to clean */ - if (++rrd_next_to_clean == rrd_ring->count) - rrd_next_to_clean = 0; - count++; - - if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { - if (!(rrd->err_flg & - (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM - | ERR_FLAG_LEN))) { - /* packet error, don't need upstream */ - buffer_info->alloced = 0; - rrd->xsz.valid = 0; - continue; - } - } - - /* Good Receive */ - pci_unmap_page(adapter->pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_FROMDEVICE); - skb = buffer_info->skb; - length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size); - - skb_put(skb, length - ETHERNET_FCS_SIZE); - - /* Receive Checksum Offload */ - atl1_rx_checksum(adapter, rrd, skb); - skb->protocol = eth_type_trans(skb, adapter->netdev); - - if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) { - u16 vlan_tag = (rrd->vlan_tag >> 4) | - ((rrd->vlan_tag & 7) << 13) | - ((rrd->vlan_tag & 8) << 9); - vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); - } else - netif_rx(skb); - - /* let protocol layer free skb */ - buffer_info->skb = NULL; - buffer_info->alloced = 0; - rrd->xsz.valid = 0; - - adapter->netdev->last_rx = jiffies; - } - - atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean); - - atl1_alloc_rx_buffers(adapter); - - /* update mailbox ? */ - if (count) { - u32 tpd_next_to_use; - u32 rfd_next_to_use; - u32 rrd_next_to_clean; - - spin_lock(&adapter->mb_lock); - - tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use); - rfd_next_to_use = - atomic_read(&adapter->rfd_ring.next_to_use); - rrd_next_to_clean = - atomic_read(&adapter->rrd_ring.next_to_clean); - value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) << - MB_RFD_PROD_INDX_SHIFT) | - ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) << - MB_RRD_CONS_INDX_SHIFT) | - ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) << - MB_TPD_PROD_INDX_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); - spin_unlock(&adapter->mb_lock); - } -} - -static void atl1_intr_tx(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - u16 sw_tpd_next_to_clean; - u16 cmb_tpd_next_to_clean; - u8 update = 0; - - sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean); - cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx); - - while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) { - struct tx_packet_desc *tpd; - update = 1; - tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean); - buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean]; - if (buffer_info->dma) { - pci_unmap_page(adapter->pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_TODEVICE); - buffer_info->dma = 0; - } - - if (buffer_info->skb) { - dev_kfree_skb_irq(buffer_info->skb); - buffer_info->skb = NULL; - } - tpd->buffer_addr = 0; - tpd->desc.data = 0; - - if (++sw_tpd_next_to_clean == tpd_ring->count) - sw_tpd_next_to_clean = 0; - } - atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean); - - if (netif_queue_stopped(adapter->netdev) - && netif_carrier_ok(adapter->netdev)) - netif_wake_queue(adapter->netdev); -} - -static void atl1_check_for_link(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - u16 phy_data = 0; - - spin_lock(&adapter->lock); - adapter->phy_timer_pending = false; - atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); - atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); - spin_unlock(&adapter->lock); - - /* notify upper layer link down ASAP */ - if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */ - if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: %s link is down\n", - atl1_driver_name, netdev->name); - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - } - schedule_work(&adapter->link_chg_task); -} - -/* - * atl1_intr - Interrupt Handler - * @irq: interrupt number - * @data: pointer to a network interface device structure - * @pt_regs: CPU registers structure - */ -static irqreturn_t atl1_intr(int irq, void *data) -{ - /*struct atl1_adapter *adapter = ((struct net_device *)data)->priv;*/ - struct atl1_adapter *adapter = netdev_priv(data); - u32 status; - u8 update_rx; - int max_ints = 10; - - status = adapter->cmb.cmb->int_stats; - if (!status) - return IRQ_NONE; - - update_rx = 0; - - do { - /* clear CMB interrupt status at once */ - adapter->cmb.cmb->int_stats = 0; - - if (status & ISR_GPHY) /* clear phy status */ - atl1_clear_phy_int(adapter); - - /* clear ISR status, and Enable CMB DMA/Disable Interrupt */ - iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR); - - /* check if SMB intr */ - if (status & ISR_SMB) - atl1_inc_smb(adapter); - - /* check if PCIE PHY Link down */ - if (status & ISR_PHY_LINKDOWN) { - printk(KERN_DEBUG "%s: pcie phy link down %x\n", - atl1_driver_name, status); - if (netif_running(adapter->netdev)) { /* reset MAC */ - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->pcie_dma_to_rst_task); - return IRQ_HANDLED; - } - } - - /* check if DMA read/write error ? */ - if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { - printk(KERN_DEBUG - "%s: pcie DMA r/w error (status = 0x%x)\n", - atl1_driver_name, status); - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->pcie_dma_to_rst_task); - return IRQ_HANDLED; - } - - /* link event */ - if (status & ISR_GPHY) { - adapter->soft_stats.tx_carrier_errors++; - atl1_check_for_link(adapter); - } - - /* transmit event */ - if (status & ISR_CMB_TX) - atl1_intr_tx(adapter); - - /* rx exception */ - if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | - ISR_RRD_OV | ISR_HOST_RFD_UNRUN | - ISR_HOST_RRD_OV | ISR_CMB_RX))) { - if (status & - (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | - ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV)) - printk(KERN_INFO - "%s: rx exception: status = 0x%x\n", - atl1_driver_name, status); - atl1_intr_rx(adapter); - } - - if (--max_ints < 0) - break; - - } while ((status = adapter->cmb.cmb->int_stats)); - - /* re-enable Interrupt */ - iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR); - return IRQ_HANDLED; -} - -/* - * atl1_set_multi - Multicast and Promiscuous mode set - * @netdev: network interface device structure - * - * The set_multi entry point is called whenever the multicast address - * list or the network interface flags are updated. This routine is - * responsible for configuring the hardware for proper multicast, - * promiscuous mode, and all-multi behavior. - */ -static void atl1_set_multi(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr; - u32 rctl; - u32 hash_value; - - /* Check for Promiscuous and All Multicast modes */ - rctl = ioread32(hw->hw_addr + REG_MAC_CTRL); - if (netdev->flags & IFF_PROMISC) - rctl |= MAC_CTRL_PROMIS_EN; - else if (netdev->flags & IFF_ALLMULTI) { - rctl |= MAC_CTRL_MC_ALL_EN; - rctl &= ~MAC_CTRL_PROMIS_EN; - } else - rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); - - iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL); - - /* clear the old settings from the multicast hash table */ - iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE); - iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2)); - - /* compute mc addresses' hash value ,and put it into hash table */ - for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { - hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr); - atl1_hash_set(hw, hash_value); - } -} - -static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) -{ - u32 value; - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - /* Config MAC CTRL Register */ - value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; - /* duplex */ - if (FULL_DUPLEX == adapter->link_duplex) - value |= MAC_CTRL_DUPLX; - /* speed */ - value |= ((u32) ((SPEED_1000 == adapter->link_speed) ? - MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) << - MAC_CTRL_SPEED_SHIFT); - /* flow control */ - value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); - /* PAD & CRC */ - value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); - /* preamble length */ - value |= (((u32) adapter->hw.preamble_len - & MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); - /* vlan */ - if (adapter->vlgrp) - value |= MAC_CTRL_RMV_VLAN; - /* rx checksum - if (adapter->rx_csum) - value |= MAC_CTRL_RX_CHKSUM_EN; - */ - /* filter mode */ - value |= MAC_CTRL_BC_EN; - if (netdev->flags & IFF_PROMISC) - value |= MAC_CTRL_PROMIS_EN; - else if (netdev->flags & IFF_ALLMULTI) - value |= MAC_CTRL_MC_ALL_EN; - /* value |= MAC_CTRL_LOOPBACK; */ - iowrite32(value, hw->hw_addr + REG_MAC_CTRL); -} - -static u32 atl1_check_link(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - u32 ret_val; - u16 speed, duplex, phy_data; - int reconfig = 0; - - /* MII_BMSR must read twice */ - atl1_read_phy_reg(hw, MII_BMSR, &phy_data); - atl1_read_phy_reg(hw, MII_BMSR, &phy_data); - if (!(phy_data & BMSR_LSTATUS)) { /* link down */ - if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: link is down\n", - atl1_driver_name); - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - return ATL1_SUCCESS; - } - - /* Link Up */ - ret_val = atl1_get_speed_and_duplex(hw, &speed, &duplex); - if (ret_val) - return ret_val; - - switch (hw->media_type) { - case MEDIA_TYPE_1000M_FULL: - if (speed != SPEED_1000 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_100M_FULL: - if (speed != SPEED_100 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_100M_HALF: - if (speed != SPEED_100 || duplex != HALF_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_10M_FULL: - if (speed != SPEED_10 || duplex != FULL_DUPLEX) - reconfig = 1; - break; - case MEDIA_TYPE_10M_HALF: - if (speed != SPEED_10 || duplex != HALF_DUPLEX) - reconfig = 1; - break; - } - - /* link result is our setting */ - if (!reconfig) { - if (adapter->link_speed != speed - || adapter->link_duplex != duplex) { - adapter->link_speed = speed; - adapter->link_duplex = duplex; - atl1_setup_mac_ctrl(adapter); - printk(KERN_INFO "%s: %s link is up %d Mbps %s\n", - atl1_driver_name, netdev->name, - adapter->link_speed, - adapter->link_duplex == - FULL_DUPLEX ? "full duplex" : "half duplex"); - } - if (!netif_carrier_ok(netdev)) { /* Link down -> Up */ - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } - return ATL1_SUCCESS; - } - - /* change orignal link status */ - if (netif_carrier_ok(netdev)) { - adapter->link_speed = SPEED_0; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - - if (hw->media_type != MEDIA_TYPE_AUTO_SENSOR && - hw->media_type != MEDIA_TYPE_1000M_FULL) { - switch (hw->media_type) { - case MEDIA_TYPE_100M_FULL: - phy_data = MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 | - MII_CR_RESET; - break; - case MEDIA_TYPE_100M_HALF: - phy_data = MII_CR_SPEED_100 | MII_CR_RESET; - break; - case MEDIA_TYPE_10M_FULL: - phy_data = - MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET; - break; - default: /* MEDIA_TYPE_10M_HALF: */ - phy_data = MII_CR_SPEED_10 | MII_CR_RESET; - break; - } - atl1_write_phy_reg(hw, MII_BMCR, phy_data); - return ATL1_SUCCESS; - } - - /* auto-neg, insert timer to re-config phy */ - if (!adapter->phy_timer_pending) { - adapter->phy_timer_pending = true; - mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ); - } - - return ATL1_SUCCESS; -} - -static void set_flow_ctrl_old(struct atl1_adapter *adapter) -{ - u32 hi, lo, value; - - /* RFD Flow Control */ - value = adapter->rfd_ring.count; - hi = value / 16; - if (hi < 2) - hi = 2; - lo = value * 7 / 8; - - value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RXF_PAUSE_THRESH); - - /* RRD Flow Control */ - value = adapter->rrd_ring.count; - lo = value / 16; - hi = value * 7 / 8; - if (lo < 2) - lo = 2; - value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RRD_PAUSE_THRESH); -} - -static void set_flow_ctrl_new(struct atl1_hw *hw) -{ - u32 hi, lo, value; - - /* RXF Flow Control */ - value = ioread32(hw->hw_addr + REG_SRAM_RXF_LEN); - lo = value / 16; - if (lo < 192) - lo = 192; - hi = value * 7 / 8; - if (hi < lo) - hi = lo + 16; - value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_RXF_PAUSE_THRESH); - - /* RRD Flow Control */ - value = ioread32(hw->hw_addr + REG_SRAM_RRD_LEN); - lo = value / 8; - hi = value * 7 / 8; - if (lo < 2) - lo = 2; - if (hi < lo) - hi = lo + 3; - value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) | - ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH); -} - -/* - * atl1_configure - Configure Transmit&Receive Unit after Reset - * @adapter: board private structure - * - * Configure the Tx /Rx unit of the MAC after a reset. - */ -static u32 atl1_configure(struct atl1_adapter *adapter) -{ - struct atl1_hw *hw = &adapter->hw; - u32 value; - - /* clear interrupt status */ - iowrite32(0xffffffff, adapter->hw.hw_addr + REG_ISR); - - /* set MAC Address */ - value = (((u32) hw->mac_addr[2]) << 24) | - (((u32) hw->mac_addr[3]) << 16) | - (((u32) hw->mac_addr[4]) << 8) | - (((u32) hw->mac_addr[5])); - iowrite32(value, hw->hw_addr + REG_MAC_STA_ADDR); - value = (((u32) hw->mac_addr[0]) << 8) | (((u32) hw->mac_addr[1])); - iowrite32(value, hw->hw_addr + (REG_MAC_STA_ADDR + 4)); - - /* tx / rx ring */ - - /* HI base address */ - iowrite32((u32) ((adapter->tpd_ring.dma & 0xffffffff00000000ULL) >> 32), - hw->hw_addr + REG_DESC_BASE_ADDR_HI); - /* LO base address */ - iowrite32((u32) (adapter->rfd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_RFD_ADDR_LO); - iowrite32((u32) (adapter->rrd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_RRD_ADDR_LO); - iowrite32((u32) (adapter->tpd_ring.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_TPD_ADDR_LO); - iowrite32((u32) (adapter->cmb.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_CMB_ADDR_LO); - iowrite32((u32) (adapter->smb.dma & 0x00000000ffffffffULL), - hw->hw_addr + REG_DESC_SMB_ADDR_LO); - - /* element count */ - value = adapter->rrd_ring.count; - value <<= 16; - value += adapter->rfd_ring.count; - iowrite32(value, hw->hw_addr + REG_DESC_RFD_RRD_RING_SIZE); - iowrite32(adapter->tpd_ring.count, hw->hw_addr + REG_DESC_TPD_RING_SIZE); - - /* Load Ptr */ - iowrite32(1, hw->hw_addr + REG_LOAD_PTR); - - /* config Mailbox */ - value = ((atomic_read(&adapter->tpd_ring.next_to_use) - & MB_TPD_PROD_INDX_MASK) << MB_TPD_PROD_INDX_SHIFT) | - ((atomic_read(&adapter->rrd_ring.next_to_clean) - & MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) | - ((atomic_read(&adapter->rfd_ring.next_to_use) - & MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAILBOX); - - /* config IPG/IFG */ - value = (((u32) hw->ipgt & MAC_IPG_IFG_IPGT_MASK) - << MAC_IPG_IFG_IPGT_SHIFT) | - (((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) - << MAC_IPG_IFG_MIFG_SHIFT) | - (((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) - << MAC_IPG_IFG_IPGR1_SHIFT) | - (((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) - << MAC_IPG_IFG_IPGR2_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAC_IPG_IFG); - - /* config Half-Duplex Control */ - value = ((u32) hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) | - (((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) - << MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) | - MAC_HALF_DUPLX_CTRL_EXC_DEF_EN | - (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) | - (((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) - << MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT); - iowrite32(value, hw->hw_addr + REG_MAC_HALF_DUPLX_CTRL); - - /* set Interrupt Moderator Timer */ - iowrite16(adapter->imt, hw->hw_addr + REG_IRQ_MODU_TIMER_INIT); - iowrite32(MASTER_CTRL_ITIMER_EN, hw->hw_addr + REG_MASTER_CTRL); - - /* set Interrupt Clear Timer */ - iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER); - - /* set MTU, 4 : VLAN */ - iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU); - - /* jumbo size & rrd retirement timer */ - value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) - << RXQ_JMBOSZ_TH_SHIFT) | - (((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK) - << RXQ_JMBO_LKAH_SHIFT) | - (((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK) - << RXQ_RRD_TIMER_SHIFT); - iowrite32(value, hw->hw_addr + REG_RXQ_JMBOSZ_RRDTIM); - - /* Flow Control */ - switch (hw->dev_rev) { - case 0x8001: - case 0x9001: - case 0x9002: - case 0x9003: - set_flow_ctrl_old(adapter); - break; - default: - set_flow_ctrl_new(hw); - break; - } - - /* config TXQ */ - value = (((u32) hw->tpd_burst & TXQ_CTRL_TPD_BURST_NUM_MASK) - << TXQ_CTRL_TPD_BURST_NUM_SHIFT) | - (((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK) - << TXQ_CTRL_TXF_BURST_NUM_SHIFT) | - (((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK) - << TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN; - iowrite32(value, hw->hw_addr + REG_TXQ_CTRL); - - /* min tpd fetch gap & tx jumbo packet size threshold for taskoffload */ - value = (((u32) hw->tx_jumbo_task_th & TX_JUMBO_TASK_TH_MASK) - << TX_JUMBO_TASK_TH_SHIFT) | - (((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK) - << TX_TPD_MIN_IPG_SHIFT); - iowrite32(value, hw->hw_addr + REG_TX_JUMBO_TASK_TH_TPD_IPG); - - /* config RXQ */ - value = (((u32) hw->rfd_burst & RXQ_CTRL_RFD_BURST_NUM_MASK) - << RXQ_CTRL_RFD_BURST_NUM_SHIFT) | - (((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK) - << RXQ_CTRL_RRD_BURST_THRESH_SHIFT) | - (((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK) - << RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) | - RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN; - iowrite32(value, hw->hw_addr + REG_RXQ_CTRL); - - /* config DMA Engine */ - value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) - << DMA_CTRL_DMAR_BURST_LEN_SHIFT) | - ((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK) - << DMA_CTRL_DMAR_BURST_LEN_SHIFT) | - DMA_CTRL_DMAR_EN | DMA_CTRL_DMAW_EN; - value |= (u32) hw->dma_ord; - if (atl1_rcb_128 == hw->rcb_value) - value |= DMA_CTRL_RCB_VALUE; - iowrite32(value, hw->hw_addr + REG_DMA_CTRL); - - /* config CMB / SMB */ - value = hw->cmb_rrd | ((u32) hw->cmb_tpd << 16); - iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH); - value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16); - iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER); - iowrite32(hw->smb_timer, hw->hw_addr + REG_SMB_TIMER); - - /* --- enable CMB / SMB */ - value = CSMB_CTRL_CMB_EN | CSMB_CTRL_SMB_EN; - iowrite32(value, hw->hw_addr + REG_CSMB_CTRL); - - value = ioread32(adapter->hw.hw_addr + REG_ISR); - if (unlikely((value & ISR_PHY_LINKDOWN) != 0)) - value = 1; /* config failed */ - else - value = 0; - - /* clear all interrupt status */ - iowrite32(0x3fffffff, adapter->hw.hw_addr + REG_ISR); - iowrite32(0, adapter->hw.hw_addr + REG_ISR); - return value; -} - -/* - * atl1_irq_disable - Mask off interrupt generation on the NIC - * @adapter: board private structure - */ -static void atl1_irq_disable(struct atl1_adapter *adapter) -{ - atomic_inc(&adapter->irq_sem); - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - ioread32(adapter->hw.hw_addr + REG_IMR); - synchronize_irq(adapter->pdev->irq); -} - -static void atl1_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - u32 ctrl; - - spin_lock_irqsave(&adapter->lock, flags); - /* atl1_irq_disable(adapter); */ - adapter->vlgrp = grp; - - if (grp) { - /* enable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl |= MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } else { - /* disable VLAN tag insert/strip */ - ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_RMV_VLAN; - iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL); - } - - /* atl1_irq_enable(adapter); */ - spin_unlock_irqrestore(&adapter->lock, flags); -} - -/* FIXME: justify or remove -- CHS */ -static void atl1_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -{ - /* We don't do Vlan filtering */ - return; -} - -/* FIXME: this looks wrong too -- CHS */ -static void atl1_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - /* atl1_irq_disable(adapter); */ - if (adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; - /* atl1_irq_enable(adapter); */ - spin_unlock_irqrestore(&adapter->lock, flags); - /* We don't do Vlan filtering */ - return; -} - -static void atl1_restore_vlan(struct atl1_adapter *adapter) -{ - atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp); - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if (!adapter->vlgrp->vlan_devices[vid]) - continue; - atl1_vlan_rx_add_vid(adapter->netdev, vid); - } - } -} - -static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring) -{ - u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); - u16 next_to_use = atomic_read(&tpd_ring->next_to_use); - return ((next_to_clean > - next_to_use) ? next_to_clean - next_to_use - - 1 : tpd_ring->count + next_to_clean - next_to_use - 1); -} - -static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, - struct tso_param *tso) -{ - /* We enter this function holding a spinlock. */ - u8 ipofst; - int err; - - if (skb_shinfo(skb)->gso_size) { - if (skb_header_cloned(skb)) { - err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - if (unlikely(err)) - return err; - } - - if (skb->protocol == ntohs(ETH_P_IP)) { - skb->nh.iph->tot_len = 0; - skb->nh.iph->check = 0; - skb->h.th->check = - ~csum_tcpudp_magic(skb->nh.iph->saddr, - skb->nh.iph->daddr, 0, - IPPROTO_TCP, 0); - ipofst = skb->nh.raw - skb->data; - if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */ - tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT; - - tso->tsopl |= (skb->nh.iph->ihl & - CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT; - tso->tsopl |= ((skb->h.th->doff << 2) & - TSO_PARAM_TCPHDRLEN_MASK) << TSO_PARAM_TCPHDRLEN_SHIFT; - tso->tsopl |= (skb_shinfo(skb)->gso_size & - TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_TCPCKSUM_SHIFT; - tso->tsopl |= 1 << TSO_PARAM_SEGMENT_SHIFT; - return true; - } - } - return false; -} - -static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, - struct csum_param *csum) -{ - u8 css, cso; - - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { - cso = skb->h.raw - skb->data; - css = (skb->h.raw + skb->csum) - skb->data; - if (unlikely(cso & 0x1)) { - printk(KERN_DEBUG "%s: payload offset != even number\n", - atl1_driver_name); - return -1; - } - csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) << - CSUM_PARAM_PLOADOFFSET_SHIFT; - csum->csumpl |= (css & CSUM_PARAM_XSUMOFFSET_MASK) << - CSUM_PARAM_XSUMOFFSET_SHIFT; - csum->csumpl |= 1 << CSUM_PARAM_CUSTOMCKSUM_SHIFT; - return true; - } - - return true; -} - -static void atl1_tx_map(struct atl1_adapter *adapter, - struct sk_buff *skb, bool tcp_seg) -{ - /* We enter this function holding a spinlock. */ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - struct page *page; - int first_buf_len = skb->len; - unsigned long offset; - unsigned int nr_frags; - unsigned int f; - u16 tpd_next_to_use; - u16 proto_hdr_len; - u16 i, m, len12; - - first_buf_len -= skb->data_len; - nr_frags = skb_shinfo(skb)->nr_frags; - tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); - buffer_info->skb = NULL; /* put skb in last TPD */ - - if (tcp_seg) { - /* TSO/GSO */ - proto_hdr_len = - ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - buffer_info->length = proto_hdr_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(adapter->pdev, page, - offset, proto_hdr_len, - PCI_DMA_TODEVICE); - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - - if (first_buf_len > proto_hdr_len) { - len12 = first_buf_len - proto_hdr_len; - m = (len12 + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - for (i = 0; i < m; i++) { - buffer_info = - &tpd_ring->buffer_info[tpd_next_to_use]; - buffer_info->skb = NULL; - buffer_info->length = - (MAX_TX_BUF_LEN >= - len12) ? MAX_TX_BUF_LEN : len12; - len12 -= buffer_info->length; - page = virt_to_page(skb->data + - (proto_hdr_len + - i * MAX_TX_BUF_LEN)); - offset = (unsigned long)(skb->data + - (proto_hdr_len + - i * MAX_TX_BUF_LEN)) & - ~PAGE_MASK; - buffer_info->dma = - pci_map_page(adapter->pdev, page, offset, - buffer_info->length, - PCI_DMA_TODEVICE); - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - } - } else { - /* not TSO/GSO */ - buffer_info->length = first_buf_len; - page = virt_to_page(skb->data); - offset = (unsigned long)skb->data & ~PAGE_MASK; - buffer_info->dma = pci_map_page(adapter->pdev, page, - offset, first_buf_len, - PCI_DMA_TODEVICE); - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - - for (f = 0; f < nr_frags; f++) { - struct skb_frag_struct *frag; - u16 lenf, i, m; - - frag = &skb_shinfo(skb)->frags[f]; - lenf = frag->size; - - m = (lenf + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - for (i = 0; i < m; i++) { - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); - buffer_info->skb = NULL; - buffer_info->length = - (lenf > MAX_TX_BUF_LEN) ? MAX_TX_BUF_LEN : lenf; - lenf -= buffer_info->length; - buffer_info->dma = - pci_map_page(adapter->pdev, frag->page, - frag->page_offset + i * MAX_TX_BUF_LEN, - buffer_info->length, PCI_DMA_TODEVICE); - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - } - - /* last tpd's buffer-info */ - buffer_info->skb = skb; -} - -static void atl1_tx_queue(struct atl1_adapter *adapter, int count, - union tpd_descr *descr) -{ - /* We enter this function holding a spinlock. */ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - int j; - u32 val; - struct atl1_buffer *buffer_info; - struct tx_packet_desc *tpd; - u16 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use); - - for (j = 0; j < count; j++) { - buffer_info = &tpd_ring->buffer_info[tpd_next_to_use]; - tpd = ATL1_TPD_DESC(&adapter->tpd_ring, tpd_next_to_use); - tpd->desc.csum.csumpu = descr->csum.csumpu; - tpd->desc.csum.csumpl = descr->csum.csumpl; - tpd->desc.tso.tsopu = descr->tso.tsopu; - tpd->desc.tso.tsopl = descr->tso.tsopl; - tpd->buffer_addr = cpu_to_le64(buffer_info->dma); - tpd->desc.data = descr->data; - tpd->desc.csum.csumpu |= (cpu_to_le16(buffer_info->length) & - CSUM_PARAM_BUFLEN_MASK) << CSUM_PARAM_BUFLEN_SHIFT; - - val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) & - TSO_PARAM_SEGMENT_MASK; - if (val && !j) - tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT; - - if (j == (count - 1)) - tpd->desc.csum.csumpl |= 1 << CSUM_PARAM_EOP_SHIFT; - - if (++tpd_next_to_use == tpd_ring->count) - tpd_next_to_use = 0; - } - /* - * Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). - */ - wmb(); - - atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use); -} - -static void atl1_update_mailbox(struct atl1_adapter *adapter) -{ - unsigned long flags; - u32 tpd_next_to_use; - u32 rfd_next_to_use; - u32 rrd_next_to_clean; - u32 value; - - spin_lock_irqsave(&adapter->mb_lock, flags); - - tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use); - rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use); - rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean); - - value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) << - MB_RFD_PROD_INDX_SHIFT) | - ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) << - MB_RRD_CONS_INDX_SHIFT) | - ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) << - MB_TPD_PROD_INDX_SHIFT); - iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX); - - spin_unlock_irqrestore(&adapter->mb_lock, flags); -} - -static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int len = skb->len; - int tso; - int count = 1; - int ret_val; - u32 val; - union tpd_descr param; - u16 frag_size; - u16 vlan_tag; - unsigned long flags; - unsigned int nr_frags = 0; - unsigned int mss = 0; - unsigned int f; - unsigned int proto_hdr_len; - - len -= skb->data_len; - - if (unlikely(skb->len == 0)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - param.data = 0; - param.tso.tsopu = 0; - param.tso.tsopl = 0; - param.csum.csumpu = 0; - param.csum.csumpl = 0; - - /* nr_frags will be nonzero if we're doing scatter/gather (SG) */ - nr_frags = skb_shinfo(skb)->nr_frags; - for (f = 0; f < nr_frags; f++) { - frag_size = skb_shinfo(skb)->frags[f].size; - if (frag_size) - count += - (frag_size + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - } - - /* mss will be nonzero if we're doing segment offload (TSO/GSO) */ - mss = skb_shinfo(skb)->gso_size; - if (mss) { - if (skb->protocol == ntohs(ETH_P_IP)) { - proto_hdr_len = ((skb->h.raw - skb->data) + - (skb->h.th->doff << 2)); - if (unlikely(proto_hdr_len > len)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - /* need additional TPD ? */ - if (proto_hdr_len != len) - count += (len - proto_hdr_len + - MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN; - } - } - - local_irq_save(flags); - if (!spin_trylock(&adapter->lock)) { - /* Can't get lock - tell upper layer to requeue */ - local_irq_restore(flags); - printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name); - return NETDEV_TX_LOCKED; - } - - if (tpd_avail(&adapter->tpd_ring) < count) { - /* not enough descriptors */ - netif_stop_queue(netdev); - spin_unlock_irqrestore(&adapter->lock, flags); - printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name); - return NETDEV_TX_BUSY; - } - - param.data = 0; - - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { - vlan_tag = vlan_tx_tag_get(skb); - vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | - ((vlan_tag >> 9) & 0x8); - param.csum.csumpl |= 1 << CSUM_PARAM_INSVLAG_SHIFT; - param.csum.csumpu |= (vlan_tag & CSUM_PARAM_VALANTAG_MASK) << - CSUM_PARAM_VALAN_SHIFT; - } - - tso = atl1_tso(adapter, skb, ¶m.tso); - if (tso < 0) { - spin_unlock_irqrestore(&adapter->lock, flags); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - if (!tso) { - ret_val = atl1_tx_csum(adapter, skb, ¶m.csum); - if (ret_val < 0) { - spin_unlock_irqrestore(&adapter->lock, flags); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - } - - val = (param.csum.csumpl >> CSUM_PARAM_SEGMENT_SHIFT) & - CSUM_PARAM_SEGMENT_MASK; - atl1_tx_map(adapter, skb, 1 == val); - atl1_tx_queue(adapter, count, ¶m); - netdev->trans_start = jiffies; - spin_unlock_irqrestore(&adapter->lock, flags); - atl1_update_mailbox(adapter); - return NETDEV_TX_OK; -} - -/* - * atl1_get_stats - Get System Network Statistics - * @netdev: network interface device structure - * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. - */ -static struct net_device_stats *atl1_get_stats(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - return &adapter->net_stats; -} - -/* - * atl1_clean_rx_ring - Free RFD Buffers - * @adapter: board private structure - */ -static void atl1_clean_rx_ring(struct atl1_adapter *adapter) -{ - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_buffer *buffer_info; - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - unsigned int i; - - /* Free all the Rx ring sk_buffs */ - for (i = 0; i < rfd_ring->count; i++) { - buffer_info = &rfd_ring->buffer_info[i]; - if (buffer_info->dma) { - pci_unmap_page(pdev, - buffer_info->dma, - buffer_info->length, - PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; - } - if (buffer_info->skb) { - dev_kfree_skb(buffer_info->skb); - buffer_info->skb = NULL; - } - } - - size = sizeof(struct atl1_buffer) * rfd_ring->count; - memset(rfd_ring->buffer_info, 0, size); - - /* Zero out the descriptor ring */ - memset(rfd_ring->desc, 0, rfd_ring->size); - - rfd_ring->next_to_clean = 0; - atomic_set(&rfd_ring->next_to_use, 0); - - rrd_ring->next_to_use = 0; - atomic_set(&rrd_ring->next_to_clean, 0); -} - -/* - * atl1_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure - */ -static void atl1_clean_tx_ring(struct atl1_adapter *adapter) -{ - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_buffer *buffer_info; - struct pci_dev *pdev = adapter->pdev; - unsigned long size; - unsigned int i; - - /* Free all the Tx ring sk_buffs */ - for (i = 0; i < tpd_ring->count; i++) { - buffer_info = &tpd_ring->buffer_info[i]; - if (buffer_info->dma) { - pci_unmap_page(pdev, buffer_info->dma, - buffer_info->length, PCI_DMA_TODEVICE); - buffer_info->dma = 0; - } - } - - for (i = 0; i < tpd_ring->count; i++) { - buffer_info = &tpd_ring->buffer_info[i]; - if (buffer_info->skb) { - dev_kfree_skb_any(buffer_info->skb); - buffer_info->skb = NULL; - } - } - - size = sizeof(struct atl1_buffer) * tpd_ring->count; - memset(tpd_ring->buffer_info, 0, size); - - /* Zero out the descriptor ring */ - memset(tpd_ring->desc, 0, tpd_ring->size); - - atomic_set(&tpd_ring->next_to_use, 0); - atomic_set(&tpd_ring->next_to_clean, 0); -} - -/* - * atl1_free_ring_resources - Free Tx / RX descriptor Resources - * @adapter: board private structure - * - * Free all transmit software resources - */ -void atl1_free_ring_resources(struct atl1_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring; - struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring; - struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring; - struct atl1_ring_header *ring_header = &adapter->ring_header; - - atl1_clean_tx_ring(adapter); - atl1_clean_rx_ring(adapter); - - kfree(tpd_ring->buffer_info); - pci_free_consistent(pdev, ring_header->size, ring_header->desc, - ring_header->dma); - - tpd_ring->buffer_info = NULL; - tpd_ring->desc = NULL; - tpd_ring->dma = 0; - - rfd_ring->buffer_info = NULL; - rfd_ring->desc = NULL; - rfd_ring->dma = 0; - - rrd_ring->desc = NULL; - rrd_ring->dma = 0; -} - -s32 atl1_up(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - int err; - int irq_flags = IRQF_SAMPLE_RANDOM; - - /* hardware has been reset, we need to reload some things */ - atl1_set_multi(netdev); - atl1_restore_vlan(adapter); - err = atl1_alloc_rx_buffers(adapter); - if (unlikely(!err)) /* no RX BUFFER allocated */ - return -ENOMEM; - - if (unlikely(atl1_configure(adapter))) { - err = -EIO; - goto err_up; - } - - err = pci_enable_msi(adapter->pdev); - if (err) { - dev_info(&adapter->pdev->dev, - "Unable to enable MSI: %d\n", err); - irq_flags |= IRQF_SHARED; - } - - err = request_irq(adapter->pdev->irq, &atl1_intr, irq_flags, - netdev->name, netdev); - if (unlikely(err)) - goto err_up; - - mod_timer(&adapter->watchdog_timer, jiffies); - atl1_irq_enable(adapter); - atl1_check_link(adapter); - return 0; - - /* FIXME: unreachable code! -- CHS */ - /* free irq disable any interrupt */ - iowrite32(0, adapter->hw.hw_addr + REG_IMR); - free_irq(adapter->pdev->irq, netdev); - -err_up: - pci_disable_msi(adapter->pdev); - /* free rx_buffers */ - atl1_clean_rx_ring(adapter); - return err; -} - -void atl1_down(struct atl1_adapter *adapter) -{ - struct net_device *netdev = adapter->netdev; - - del_timer_sync(&adapter->watchdog_timer); - del_timer_sync(&adapter->phy_config_timer); - adapter->phy_timer_pending = false; - - atl1_irq_disable(adapter); - free_irq(adapter->pdev->irq, netdev); - pci_disable_msi(adapter->pdev); - atl1_reset_hw(&adapter->hw); - adapter->cmb.cmb->int_stats = 0; - - adapter->link_speed = SPEED_0; - adapter->link_duplex = -1; - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - atl1_clean_tx_ring(adapter); - atl1_clean_rx_ring(adapter); -} - -/* - * atl1_change_mtu - Change the Maximum Transfer Unit - * @netdev: network interface device structure - * @new_mtu: new value for maximum frame size - * - * Returns 0 on success, negative on failure - */ -static int atl1_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int old_mtu = netdev->mtu; - int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - - if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || - (max_frame > MAX_JUMBO_FRAME_SIZE)) { - printk(KERN_WARNING "%s: invalid MTU setting\n", - atl1_driver_name); - return -EINVAL; - } - - adapter->hw.max_frame_size = max_frame; - adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3; - adapter->rx_buffer_len = (max_frame + 7) & ~7; - adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8; - - netdev->mtu = new_mtu; - if ((old_mtu != new_mtu) && netif_running(netdev)) { - atl1_down(adapter); - atl1_up(adapter); - } - - return 0; -} - -/* - * atl1_set_mac - Change the Ethernet Address of the NIC - * @netdev: network interface device structure - * @p: pointer to an address structure - * - * Returns 0 on success, negative on failure - */ -static int atl1_set_mac(struct net_device *netdev, void *p) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - struct sockaddr *addr = p; - - if (netif_running(netdev)) - return -EBUSY; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); - - atl1_set_mac_addr(&adapter->hw); - return 0; -} - -/* - * atl1_watchdog - Timer Call-back - * @data: pointer to netdev cast into an unsigned long - */ -static void atl1_watchdog(unsigned long data) -{ - struct atl1_adapter *adapter = (struct atl1_adapter *)data; - - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); -} - -static int mdio_read(struct net_device *netdev, int phy_id, int reg_num) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - u16 result; - - atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result); - - return result; -} - -static void mdio_write(struct net_device *netdev, int phy_id, int reg_num, int val) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - - atl1_write_phy_reg(&adapter->hw, reg_num, val); -} - -/* - * atl1_mii_ioctl - - * @netdev: - * @ifreq: - * @cmd: - */ -static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - int retval; - - if (!netif_running(netdev)) - return -EINVAL; - - spin_lock_irqsave(&adapter->lock, flags); - retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); - spin_unlock_irqrestore(&adapter->lock, flags); - - return retval; -} - -/* - * atl1_ioctl - - * @netdev: - * @ifreq: - * @cmd: - */ -static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) -{ - switch (cmd) { - case SIOCGMIIPHY: - case SIOCGMIIREG: - case SIOCSMIIREG: - return atl1_mii_ioctl(netdev, ifr, cmd); - default: - return -EOPNOTSUPP; - } -} - -/* - * atl1_tx_timeout - Respond to a Tx Hang - * @netdev: network interface device structure - */ -static void atl1_tx_timeout(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - /* Do the reset outside of interrupt context */ - schedule_work(&adapter->tx_timeout_task); -} - -/* - * atl1_phy_config - Timer Call-back - * @data: pointer to netdev cast into an unsigned long - */ -static void atl1_phy_config(unsigned long data) -{ - struct atl1_adapter *adapter = (struct atl1_adapter *)data; - struct atl1_hw *hw = &adapter->hw; - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - adapter->phy_timer_pending = false; - atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); - atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg); - atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -int atl1_reset(struct atl1_adapter *adapter) -{ - int ret; - - ret = atl1_reset_hw(&adapter->hw); - if (ret != ATL1_SUCCESS) - return ret; - return atl1_init_hw(&adapter->hw); -} - -/* - * atl1_open - Called when a network interface is made active - * @netdev: network interface device structure - * - * Returns 0 on success, negative value on failure - * - * The open entry point is called when a network interface is made - * active by the system (IFF_UP). At this point all resources needed - * for transmit and receive operations are allocated, the interrupt - * handler is registered with the OS, the watchdog timer is started, - * and the stack is notified that the interface is ready. - */ -static int atl1_open(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - int err; - - /* allocate transmit descriptors */ - err = atl1_setup_ring_resources(adapter); - if (err) - return err; - - err = atl1_up(adapter); - if (err) - goto err_up; - - return 0; - -err_up: - atl1_reset(adapter); - return err; -} - -/* - * atl1_close - Disables a network interface - * @netdev: network interface device structure - * - * Returns 0, this is not allowed to fail - * - * The close entry point is called when an interface is de-activated - * by the OS. The hardware is still under the drivers control, but - * needs to be disabled. A global MAC reset is issued to stop the - * hardware, and all transmit and receive resources are freed. - */ -static int atl1_close(struct net_device *netdev) -{ - struct atl1_adapter *adapter = netdev_priv(netdev); - atl1_down(adapter); - atl1_free_ring_resources(adapter); - return 0; -} - -/* - * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT - * will assert. We do soft reset <0x1400=1> according - * with the SPEC. BUT, it seemes that PCIE or DMA - * state-machine will not be reset. DMAR_TO_INT will - * assert again and again. - */ -static void atl1_tx_timeout_task(struct work_struct *work) -{ - struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, tx_timeout_task); - struct net_device *netdev = adapter->netdev; - - netif_device_detach(netdev); - atl1_down(adapter); - atl1_up(adapter); - netif_device_attach(netdev); -} - -/* - * atl1_link_chg_task - deal with link change event Out of interrupt context - */ -static void atl1_link_chg_task(struct work_struct *work) -{ - struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, link_chg_task); - unsigned long flags; - - spin_lock_irqsave(&adapter->lock, flags); - atl1_check_link(adapter); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -/* - * atl1_pcie_patch - Patch for PCIE module - */ -static void atl1_pcie_patch(struct atl1_adapter *adapter) -{ - u32 value; - value = 0x6500; - iowrite32(value, adapter->hw.hw_addr + 0x12FC); - /* pcie flow control mode change */ - value = ioread32(adapter->hw.hw_addr + 0x1008); - value |= 0x8000; - iowrite32(value, adapter->hw.hw_addr + 0x1008); -} - -/* - * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400 - * on PCI Command register is disable. - * The function enable this bit. - * Brackett, 2006/03/15 - */ -static void atl1_via_workaround(struct atl1_adapter *adapter) -{ - unsigned long value; - - value = ioread16(adapter->hw.hw_addr + PCI_COMMAND); - if (value & PCI_COMMAND_INTX_DISABLE) - value &= ~PCI_COMMAND_INTX_DISABLE; - iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND); -} - -/* - * atl1_probe - Device Initialization Routine - * @pdev: PCI device information struct - * @ent: entry in atl1_pci_tbl - * - * Returns 0 on success, negative on failure - * - * atl1_probe initializes an adapter identified by a pci_dev structure. - * The OS initialization, configuring of the adapter private structure, - * and a hardware reset occur. - */ -static int __devinit atl1_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *netdev; - struct atl1_adapter *adapter; - static int cards_found = 0; - bool pci_using_64 = true; - int err; - - err = pci_enable_device(pdev); - if (err) - return err; - - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (err) { - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (err) { - printk(KERN_DEBUG - "%s: no usable DMA configuration, aborting\n", - atl1_driver_name); - goto err_dma; - } - pci_using_64 = false; - } - /* Mark all PCI regions associated with PCI device - * pdev as being reserved by owner atl1_driver_name - */ - err = pci_request_regions(pdev, atl1_driver_name); - if (err) - goto err_request_regions; - - /* Enables bus-mastering on the device and calls - * pcibios_set_master to do the needed arch specific settings - */ - pci_set_master(pdev); - - netdev = alloc_etherdev(sizeof(struct atl1_adapter)); - if (!netdev) { - err = -ENOMEM; - goto err_alloc_etherdev; - } - SET_MODULE_OWNER(netdev); - SET_NETDEV_DEV(netdev, &pdev->dev); - - pci_set_drvdata(pdev, netdev); - adapter = netdev_priv(netdev); - adapter->netdev = netdev; - adapter->pdev = pdev; - adapter->hw.back = adapter; - - adapter->hw.hw_addr = pci_iomap(pdev, 0, 0); - if (!adapter->hw.hw_addr) { - err = -EIO; - goto err_pci_iomap; - } - /* get device revision number */ - adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2)); - - /* set default ring resource counts */ - adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD; - adapter->tpd_ring.count = ATL1_DEFAULT_TPD; - - adapter->mii.dev = netdev; - adapter->mii.mdio_read = mdio_read; - adapter->mii.mdio_write = mdio_write; - adapter->mii.phy_id_mask = 0x1f; - adapter->mii.reg_num_mask = 0x1f; - - netdev->open = &atl1_open; - netdev->stop = &atl1_close; - netdev->hard_start_xmit = &atl1_xmit_frame; - netdev->get_stats = &atl1_get_stats; - netdev->set_multicast_list = &atl1_set_multi; - netdev->set_mac_address = &atl1_set_mac; - netdev->change_mtu = &atl1_change_mtu; - netdev->do_ioctl = &atl1_ioctl; - netdev->tx_timeout = &atl1_tx_timeout; - netdev->watchdog_timeo = 5 * HZ; - netdev->vlan_rx_register = atl1_vlan_rx_register; - netdev->vlan_rx_add_vid = atl1_vlan_rx_add_vid; - netdev->vlan_rx_kill_vid = atl1_vlan_rx_kill_vid; - netdev->ethtool_ops = &atl1_ethtool_ops; - adapter->bd_number = cards_found; - adapter->pci_using_64 = pci_using_64; - - /* setup the private structure */ - err = atl1_sw_init(adapter); - if (err) - goto err_common; - - netdev->features = NETIF_F_HW_CSUM; - netdev->features |= NETIF_F_SG; - netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - - /* - * FIXME - Until tso performance gets fixed, disable the feature. - * Enable it with ethtool -K if desired. - */ - /* netdev->features |= NETIF_F_TSO; */ - - if (pci_using_64) - netdev->features |= NETIF_F_HIGHDMA; - - netdev->features |= NETIF_F_LLTX; - - /* - * patch for some L1 of old version, - * the final version of L1 may not need these - * patches - */ - /* atl1_pcie_patch(adapter); */ - - /* really reset GPHY core */ - iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); - - /* - * reset the controller to - * put the device in a known good starting state - */ - if (atl1_reset_hw(&adapter->hw)) { - err = -EIO; - goto err_common; - } - - /* copy the MAC address out of the EEPROM */ - atl1_read_mac_addr(&adapter->hw); - memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); - - if (!is_valid_ether_addr(netdev->dev_addr)) { - err = -EIO; - goto err_common; - } - - atl1_check_options(adapter); - - /* pre-init the MAC, and setup link */ - err = atl1_init_hw(&adapter->hw); - if (err) { - err = -EIO; - goto err_common; - } - - atl1_pcie_patch(adapter); - /* assume we have no link for now */ - netif_carrier_off(netdev); - netif_stop_queue(netdev); - - init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &atl1_watchdog; - adapter->watchdog_timer.data = (unsigned long)adapter; - - init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl1_phy_config; - adapter->phy_config_timer.data = (unsigned long)adapter; - adapter->phy_timer_pending = false; - - INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); - - INIT_WORK(&adapter->link_chg_task, atl1_link_chg_task); - - INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); - - err = register_netdev(netdev); - if (err) - goto err_common; - - cards_found++; - atl1_via_workaround(adapter); - return 0; - -err_common: - pci_iounmap(pdev, adapter->hw.hw_addr); -err_pci_iomap: - free_netdev(netdev); -err_alloc_etherdev: - pci_release_regions(pdev); -err_dma: -err_request_regions: - pci_disable_device(pdev); - return err; -} - -/* - * atl1_remove - Device Removal Routine - * @pdev: PCI device information struct - * - * atl1_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. The could be caused by a - * Hot-Plug event, or because the driver is going to be removed from - * memory. - */ -static void __devexit atl1_remove(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter; - /* Device not available. Return. */ - if (!netdev) - return; - - adapter = netdev_priv(netdev); - iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE); - unregister_netdev(netdev); - pci_iounmap(pdev, adapter->hw.hw_addr); - pci_release_regions(pdev); - free_netdev(netdev); - pci_disable_device(pdev); -} - -#ifdef CONFIG_PM -static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter = netdev_priv(netdev); - struct atl1_hw *hw = &adapter->hw; - u32 ctrl = 0; - u32 wufc = adapter->wol; - - netif_device_detach(netdev); - if (netif_running(netdev)) - atl1_down(adapter); - - atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); - atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); - if (ctrl & BMSR_LSTATUS) - wufc &= ~ATL1_WUFC_LNKC; - - /* reduce speed to 10/100M */ - if (wufc) { - atl1_phy_enter_power_saving(hw); - /* if resume, let driver to re- setup link */ - hw->phy_configured = false; - atl1_set_mac_addr(hw); - atl1_set_multi(netdev); - - ctrl = 0; - /* turn on magic packet wol */ - if (wufc & ATL1_WUFC_MAG) - ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; - - /* turn on Link change WOL */ - if (wufc & ATL1_WUFC_LNKC) - ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); - iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); - - /* turn on all-multi mode if wake on multicast is enabled */ - ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL); - ctrl &= ~MAC_CTRL_DBG; - ctrl &= ~MAC_CTRL_PROMIS_EN; - if (wufc & ATL1_WUFC_MC) - ctrl |= MAC_CTRL_MC_ALL_EN; - else - ctrl &= ~MAC_CTRL_MC_ALL_EN; - - /* turn on broadcast mode if wake on-BC is enabled */ - if (wufc & ATL1_WUFC_BC) - ctrl |= MAC_CTRL_BC_EN; - else - ctrl &= ~MAC_CTRL_BC_EN; - - /* enable RX */ - ctrl |= MAC_CTRL_RX_EN; - iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); /* 4 == D3 cold */ - } else { - iowrite32(0, hw->hw_addr + REG_WOL_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); /* 4 == D3 cold */ - } - - pci_save_state(pdev); - pci_disable_device(pdev); - - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int atl1_resume(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct atl1_adapter *adapter = netdev_priv(netdev); - u32 ret_val; - - pci_set_power_state(pdev, 0); - pci_restore_state(pdev); - - ret_val = pci_enable_device(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - - iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); - atl1_reset(adapter); - - if (netif_running(netdev)) - atl1_up(adapter); - netif_device_attach(netdev); - - atl1_via_workaround(adapter); - - return 0; -} -#else -#define atl1_suspend NULL -#define atl1_resume NULL -#endif - -static struct pci_driver atl1_driver = { - .name = atl1_driver_name, - .id_table = atl1_pci_tbl, - .probe = atl1_probe, - .remove = __devexit_p(atl1_remove), - /* Power Managment Hooks */ - /* probably broken right now -- CHS */ - .suspend = atl1_suspend, - .resume = atl1_resume -}; - -/* - * atl1_exit_module - Driver Exit Cleanup Routine - * - * atl1_exit_module is called just before the driver is removed - * from memory. - */ -static void __exit atl1_exit_module(void) -{ - pci_unregister_driver(&atl1_driver); -} - -/* - * atl1_init_module - Driver Registration Routine - * - * atl1_init_module is the first routine called when the driver is - * loaded. All it does is register with the PCI subsystem. - */ -static int __init atl1_init_module(void) -{ - printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION); - printk(KERN_INFO "%s\n", atl1_copyright); - return pci_register_driver(&atl1_driver); -} - -module_init(atl1_init_module); -module_exit(atl1_exit_module); diff --git a/trunk/drivers/net/atl1/atl1_param.c b/trunk/drivers/net/atl1/atl1_param.c deleted file mode 100644 index c407214339f6..000000000000 --- a/trunk/drivers/net/atl1/atl1_param.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. - * Copyright(c) 2006 Chris Snook - * Copyright(c) 2006 Jay Cliburn - * - * Derived from Intel e1000 driver - * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * - * 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 -#include -#include -#include "atl1.h" - -/* - * This is the only thing that needs to be changed to adjust the - * maximum number of ports that the driver can manage. - */ -#define ATL1_MAX_NIC 4 - -#define OPTION_UNSET -1 -#define OPTION_DISABLED 0 -#define OPTION_ENABLED 1 - -#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET } - -/* - * Interrupt Moderate Timer in units of 2 us - * - * Valid Range: 10-65535 - * - * Default Value: 100 (200us) - */ -static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_int_mod_timer = 0; -module_param_array_named(int_mod_timer, int_mod_timer, int, &num_int_mod_timer, 0); -MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer"); - -/* - * flash_vendor - * - * Valid Range: 0-2 - * - * 0 - Atmel - * 1 - SST - * 2 - ST - * - * Default Value: 0 - */ -static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT; -static int num_flash_vendor = 0; -module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0); -MODULE_PARM_DESC(flash_vendor, "SPI flash vendor"); - -#define DEFAULT_INT_MOD_CNT 100 /* 200us */ -#define MAX_INT_MOD_CNT 65000 -#define MIN_INT_MOD_CNT 50 - -#define FLASH_VENDOR_DEFAULT 0 -#define FLASH_VENDOR_MIN 0 -#define FLASH_VENDOR_MAX 2 - -struct atl1_option { - enum { enable_option, range_option, list_option } type; - char *name; - char *err; - int def; - union { - struct { /* range_option info */ - int min; - int max; - } r; - struct { /* list_option info */ - int nr; - struct atl1_opt_list { - int i; - char *str; - } *p; - } l; - } arg; -}; - -static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) -{ - if (*value == OPTION_UNSET) { - *value = opt->def; - return 0; - } - - switch (opt->type) { - case enable_option: - switch (*value) { - case OPTION_ENABLED: - printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name, - opt->name); - return 0; - case OPTION_DISABLED: - printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name, - opt->name); - return 0; - } - break; - case range_option: - if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - printk(KERN_INFO "%s: %s set to %i\n", - atl1_driver_name, opt->name, *value); - return 0; - } - break; - case list_option:{ - int i; - struct atl1_opt_list *ent; - - for (i = 0; i < opt->arg.l.nr; i++) { - ent = &opt->arg.l.p[i]; - if (*value == ent->i) { - if (ent->str[0] != '\0') - printk(KERN_INFO "%s: %s\n", - atl1_driver_name, ent->str); - return 0; - } - } - } - break; - - default: - break; - } - - printk(KERN_INFO "%s: invalid %s specified (%i) %s\n", - atl1_driver_name, opt->name, *value, opt->err); - *value = opt->def; - return -1; -} - -/* - * atl1_check_options - Range Checking for Command Line Parameters - * @adapter: board private structure - * - * This routine checks all command line parameters for valid user - * input. If an invalid value is given, or if no user specified - * value exists, a default value is used. The final value is stored - * in a variable in the adapter structure. - */ -void __devinit atl1_check_options(struct atl1_adapter *adapter) -{ - int bd = adapter->bd_number; - if (bd >= ATL1_MAX_NIC) { - printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n", - atl1_driver_name, bd); - printk(KERN_NOTICE "%s: using defaults for all values\n", - atl1_driver_name); - } - { /* Interrupt Moderate Timer */ - struct atl1_option opt = { - .type = range_option, - .name = "Interrupt Moderator Timer", - .err = "using default of " - __MODULE_STRING(DEFAULT_INT_MOD_CNT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = - {.min = MIN_INT_MOD_CNT,.max = MAX_INT_MOD_CNT}} - }; - int val; - if (num_int_mod_timer > bd) { - val = int_mod_timer[bd]; - atl1_validate_option(&val, &opt); - adapter->imt = (u16) val; - } else - adapter->imt = (u16) (opt.def); - } - - { /* Flash Vendor */ - struct atl1_option opt = { - .type = range_option, - .name = "SPI Flash Vendor", - .err = "using default of " - __MODULE_STRING(FLASH_VENDOR_DEFAULT), - .def = DEFAULT_INT_MOD_CNT, - .arg = {.r = - {.min = FLASH_VENDOR_MIN,.max = - FLASH_VENDOR_MAX}} - }; - int val; - if (num_flash_vendor > bd) { - val = flash_vendor[bd]; - atl1_validate_option(&val, &opt); - adapter->hw.flash_vendor = (u8) val; - } else - adapter->hw.flash_vendor = (u8) (opt.def); - } -} diff --git a/trunk/drivers/net/bonding/bond_alb.c b/trunk/drivers/net/bonding/bond_alb.c index 217a2eedee0a..32923162179e 100644 --- a/trunk/drivers/net/bonding/bond_alb.c +++ b/trunk/drivers/net/bonding/bond_alb.c @@ -184,7 +184,7 @@ static int tlb_initialize(struct bonding *bond) spin_lock_init(&(bond_info->tx_hashtbl_lock)); - new_hashtbl = kzalloc(size, GFP_KERNEL); + new_hashtbl = kmalloc(size, GFP_KERNEL); if (!new_hashtbl) { printk(KERN_ERR DRV_NAME ": %s: Error: Failed to allocate TLB hash table\n", @@ -195,6 +195,8 @@ static int tlb_initialize(struct bonding *bond) bond_info->tx_hashtbl = new_hashtbl; + memset(bond_info->tx_hashtbl, 0, size); + for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1); } diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 8ce8fec615ba..d3801a00d3d5 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -1343,12 +1343,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) "inaccurate.\n", bond_dev->name, slave_dev->name); } - new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); + new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); if (!new_slave) { res = -ENOMEM; goto err_undo_flags; } + memset(new_slave, 0, sizeof(struct slave)); + /* save slave's original flags before calling * netdev_set_master and dev_open */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index c67f7d3c2f92..dfa035a1ad45 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -74,6 +74,8 @@ enum { #define EEPROM_MAGIC 0x38E2F10C +#define to_net_dev(class) container_of(class, struct net_device, class_dev) + #define CH_DEVICE(devid, ssid, idx) \ { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } @@ -432,12 +434,11 @@ static int setup_sge_qsets(struct adapter *adap) return 0; } -static ssize_t attr_show(struct device *d, struct device_attribute *attr, - char *buf, +static ssize_t attr_show(struct class_device *cd, char *buf, ssize_t(*format) (struct adapter *, char *)) { ssize_t len; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; /* Synchronize with ioctls that may shut down the device */ rtnl_lock(); @@ -446,15 +447,14 @@ static ssize_t attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t attr_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len, +static ssize_t attr_store(struct class_device *cd, const char *buf, size_t len, ssize_t(*set) (struct adapter *, unsigned int), unsigned int min_val, unsigned int max_val) { char *endp; ssize_t ret; unsigned int val; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -476,10 +476,9 @@ static ssize_t format_##name(struct adapter *adap, char *buf) \ { \ return sprintf(buf, "%u\n", val_expr); \ } \ -static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return attr_show(d, attr, buf, format_##name); \ + return attr_show(cd, buf, format_##name); \ } static ssize_t set_nfilters(struct adapter *adap, unsigned int val) @@ -494,10 +493,10 @@ static ssize_t set_nfilters(struct adapter *adap, unsigned int val) return 0; } -static ssize_t store_nfilters(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_nfilters(struct class_device *cd, const char *buf, + size_t len) { - return attr_store(d, attr, buf, len, set_nfilters, 0, ~0); + return attr_store(cd, buf, len, set_nfilters, 0, ~0); } static ssize_t set_nservers(struct adapter *adap, unsigned int val) @@ -510,39 +509,38 @@ static ssize_t set_nservers(struct adapter *adap, unsigned int val) return 0; } -static ssize_t store_nservers(struct device *d, struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_nservers(struct class_device *cd, const char *buf, + size_t len) { - return attr_store(d, attr, buf, len, set_nservers, 0, ~0); + return attr_store(cd, buf, len, set_nservers, 0, ~0); } #define CXGB3_ATTR_R(name, val_expr) \ CXGB3_SHOW(name, val_expr) \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) #define CXGB3_ATTR_RW(name, val_expr, store_method) \ CXGB3_SHOW(name, val_expr) \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method) +static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_method) CXGB3_ATTR_R(cam_size, t3_mc5_size(&adap->mc5)); CXGB3_ATTR_RW(nfilters, adap->params.mc5.nfilters, store_nfilters); CXGB3_ATTR_RW(nservers, adap->params.mc5.nservers, store_nservers); static struct attribute *cxgb3_attrs[] = { - &dev_attr_cam_size.attr, - &dev_attr_nfilters.attr, - &dev_attr_nservers.attr, + &class_device_attr_cam_size.attr, + &class_device_attr_nfilters.attr, + &class_device_attr_nservers.attr, NULL }; static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs }; -static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, - char *buf, int sched) +static ssize_t tm_attr_show(struct class_device *cd, char *buf, int sched) { ssize_t len; unsigned int v, addr, bpt, cpt; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2; rtnl_lock(); @@ -562,13 +560,13 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t len, int sched) +static ssize_t tm_attr_store(struct class_device *cd, const char *buf, + size_t len, int sched) { char *endp; ssize_t ret; unsigned int val; - struct adapter *adap = to_net_dev(d)->priv; + struct adapter *adap = to_net_dev(cd)->priv; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -586,17 +584,15 @@ static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, } #define TM_ATTR(name, sched) \ -static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ - char *buf) \ +static ssize_t show_##name(struct class_device *cd, char *buf) \ { \ - return tm_attr_show(d, attr, buf, sched); \ + return tm_attr_show(cd, buf, sched); \ } \ -static ssize_t store_##name(struct device *d, struct device_attribute *attr, \ - const char *buf, size_t len) \ +static ssize_t store_##name(struct class_device *cd, const char *buf, size_t len) \ { \ - return tm_attr_store(d, attr, buf, len, sched); \ + return tm_attr_store(cd, buf, len, sched); \ } \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) +static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) TM_ATTR(sched0, 0); TM_ATTR(sched1, 1); @@ -608,14 +604,14 @@ TM_ATTR(sched6, 6); TM_ATTR(sched7, 7); static struct attribute *offload_attrs[] = { - &dev_attr_sched0.attr, - &dev_attr_sched1.attr, - &dev_attr_sched2.attr, - &dev_attr_sched3.attr, - &dev_attr_sched4.attr, - &dev_attr_sched5.attr, - &dev_attr_sched6.attr, - &dev_attr_sched7.attr, + &class_device_attr_sched0.attr, + &class_device_attr_sched1.attr, + &class_device_attr_sched2.attr, + &class_device_attr_sched3.attr, + &class_device_attr_sched4.attr, + &class_device_attr_sched5.attr, + &class_device_attr_sched6.attr, + &class_device_attr_sched7.attr, NULL }; @@ -840,7 +836,7 @@ static int offload_open(struct net_device *dev) init_smt(adapter); /* Never mind if the next step fails */ - sysfs_create_group(&tdev->lldev->dev.kobj, &offload_attr_group); + sysfs_create_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); /* Call back all registered clients */ cxgb3_add_clients(tdev); @@ -865,7 +861,7 @@ static int offload_close(struct t3cdev *tdev) /* Call back all registered clients */ cxgb3_remove_clients(tdev); - sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); + sysfs_remove_group(&tdev->lldev->class_dev.kobj, &offload_attr_group); tdev->lldev = NULL; cxgb3_set_dummy_ops(tdev); @@ -2424,7 +2420,7 @@ static int __devinit init_one(struct pci_dev *pdev, else if (msi > 0 && pci_enable_msi(pdev) == 0) adapter->flags |= USING_MSI; - err = sysfs_create_group(&adapter->port[0]->dev.kobj, + err = sysfs_create_group(&adapter->port[0]->class_dev.kobj, &cxgb3_attr_group); print_port_info(adapter, ai); @@ -2456,7 +2452,7 @@ static void __devexit remove_one(struct pci_dev *pdev) struct adapter *adapter = dev->priv; t3_sge_stop(adapter); - sysfs_remove_group(&adapter->port[0]->dev.kobj, + sysfs_remove_group(&adapter->port[0]->class_dev.kobj, &cxgb3_attr_group); for_each_port(adapter, i) diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index c6b726643185..c3a02d613382 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -396,7 +396,7 @@ static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs, int n) { CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n", - n, ntohl(*(__be32 *)skbs[0]->data)); + n, ntohl(*(u32 *)skbs[0]->data)); while (n--) dev_kfree_skb_any(skbs[n]); return 0; @@ -755,7 +755,7 @@ static int do_trace(struct t3cdev *dev, struct sk_buff *skb) { struct cpl_trace_pkt *p = cplhdr(skb); - skb->protocol = htons(0xffff); + skb->protocol = 0xffff; skb->dev = dev->lldev; skb_pull(skb, sizeof(*p)); skb->mac.raw = skb->data; diff --git a/trunk/drivers/net/e2100.c b/trunk/drivers/net/e2100.c index b2b0a96218ca..c62d9c6363c6 100644 --- a/trunk/drivers/net/e2100.c +++ b/trunk/drivers/net/e2100.c @@ -355,7 +355,8 @@ e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring mem_on(ioaddr, shared_mem, (ring_offset>>8)); - memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count); + /* Packet is always in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, ei_status.mem + (ring_offset & 0xff), count, 0); mem_off(ioaddr); } diff --git a/trunk/drivers/net/es3210.c b/trunk/drivers/net/es3210.c index 822e5bfd1a71..2d2ea94a00bb 100644 --- a/trunk/drivers/net/es3210.c +++ b/trunk/drivers/net/es3210.c @@ -375,7 +375,7 @@ static void es_block_input(struct net_device *dev, int count, struct sk_buff *sk memcpy_fromio(skb->data + semi_count, ei_status.mem, count); } else { /* Packet is in one chunk. */ - memcpy_fromio(skb->data, xfer_start, count); + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/macsonic.c b/trunk/drivers/net/macsonic.c index 8ca57a0a4c11..24f6050fbf33 100644 --- a/trunk/drivers/net/macsonic.c +++ b/trunk/drivers/net/macsonic.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index d98e53efa2ef..b3bf86422734 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -2780,6 +2780,7 @@ static const struct ethtool_ops mv643xx_ethtool_ops = { .get_link = mv643xx_eth_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, + .get_strings = mv643xx_get_strings, .get_stats_count = mv643xx_get_stats_count, .get_ethtool_stats = mv643xx_get_ethtool_stats, .get_strings = mv643xx_get_strings, diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 5598d86380b4..577babd4c938 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -2016,7 +2016,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, if (!skb) goto err_out; - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, (align - 1) & (u32)skb->data); *sk_buff = skb; mapping = pci_map_single(pdev, skb->data, rx_buf_sz, @@ -2487,7 +2487,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, skb = dev_alloc_skb(pkt_size + align); if (skb) { - skb_reserve(skb, (align - 1) & (unsigned long)skb->data); + skb_reserve(skb, (align - 1) & (u32)skb->data); eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); *sk_buff = skb; rtl8169_mark_to_asic(desc, rx_buf_sz); diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 8646b64994ab..639fbc0f16f3 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -7298,7 +7298,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) { struct iphdr *ip = lro->iph; struct tcphdr *tcp = lro->tcph; - __sum16 nchk; + u16 nchk; struct stat_block *statinfo = sp->mac_control.stats_info; DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 0de0c65f945a..a5e1a513deb5 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -727,12 +727,12 @@ struct lro { struct iphdr *iph; struct tcphdr *tcph; u32 tcp_next_seq; - __be32 tcp_ack; + u32 tcp_ack; int total_len; int frags_len; int sg_num; int in_use; - __be16 window; + u16 window; u32 cur_tsval; u32 cur_tsecr; u8 saw_ts; @@ -1005,7 +1005,7 @@ static int s2io_set_swapper(struct s2io_nic * sp); static void s2io_card_down(struct s2io_nic *nic); static int s2io_card_up(struct s2io_nic *nic); static int get_xena_rev_id(struct pci_dev *pdev); -static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit); +static int wait_for_cmd_complete(void *addr, u64 busy_bit); static int s2io_add_isr(struct s2io_nic * sp); static void s2io_rem_isr(struct s2io_nic * sp); diff --git a/trunk/drivers/net/slip.c b/trunk/drivers/net/slip.c index 2f4b1de7a2b4..a0806d262fc6 100644 --- a/trunk/drivers/net/slip.c +++ b/trunk/drivers/net/slip.c @@ -1343,12 +1343,15 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif - slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); + slip_devs = kmalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); if (!slip_devs) { printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n"); return -ENOMEM; } + /* Clear the pointer array, we allocate devices when we need them */ + memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev); + /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); diff --git a/trunk/drivers/net/smc-mca.c b/trunk/drivers/net/smc-mca.c index ae1ae343beed..7122932eac90 100644 --- a/trunk/drivers/net/smc-mca.c +++ b/trunk/drivers/net/smc-mca.c @@ -482,7 +482,8 @@ static void ultramca_block_input(struct net_device *dev, int count, struct sk_bu count -= semi_count; memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/smc-ultra.c b/trunk/drivers/net/smc-ultra.c index a52b22d7db65..d70bc9795346 100644 --- a/trunk/drivers/net/smc-ultra.c +++ b/trunk/drivers/net/smc-ultra.c @@ -454,7 +454,8 @@ ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ri count -= semi_count; memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ diff --git a/trunk/drivers/net/smc-ultra32.c b/trunk/drivers/net/smc-ultra32.c index 88a30e56c64c..2c5319c62fa5 100644 --- a/trunk/drivers/net/smc-ultra32.c +++ b/trunk/drivers/net/smc-ultra32.c @@ -395,7 +395,8 @@ static void ultra32_block_input(struct net_device *dev, memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } } else { - memcpy_fromio(skb->data, xfer_start, count); + /* Packet is in one chunk -- we can copy + cksum. */ + eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 64ed8ff5b03a..bf6ff39e02bb 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1907,7 +1907,7 @@ spider_net_stop(struct net_device *netdev) spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); /* free_irq(netdev->irq, netdev);*/ - free_irq(to_pci_dev(netdev->dev.parent)->irq, netdev); + free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, SPIDER_NET_DMA_TX_FEND_VALUE); diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index e136bae61970..135c0987deae 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -3380,7 +3380,7 @@ static int tg3_rx(struct tg3 *tp, int budget) } next_pkt_nopost: sw_idx++; - sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1); + sw_idx %= TG3_RX_RCB_RING_SIZE(tp); /* Refresh hw_idx to see if there is new work */ if (sw_idx == hw_idx) { diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 31c97a6591a4..abb8611c5a91 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -1709,13 +1709,75 @@ static void adjust_link(struct net_device *dev) if (mii_info->speed != ugeth->oldspeed) { switch (mii_info->speed) { case 1000: - ugeth->ug_info->enet_interface = ENET_1000_RGMII; +#ifdef CONFIG_PPC_MPC836x +/* FIXME: This code is for 100Mbs BUG fixing, +remove this when it is fixed!!! */ + if (ugeth->ug_info->enet_interface == + ENET_1000_GMII) + /* Run the commands which initialize the PHY */ + { + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, 0x1b); + tempval |= 0x000f; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | BMCR_RESET)); + } else if (ugeth->ug_info->enet_interface == + ENET_1000_RGMII) + /* Run the commands which initialize the PHY */ + { + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, 0x1b); + tempval = (tempval & ~0x000f) | 0x000b; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth-> + dev, mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | BMCR_RESET)); + } + msleep(4000); +#endif /* CONFIG_MPC8360 */ + adjust_enet_interface(ugeth); break; case 100: - ugeth->ug_info->enet_interface = ENET_100_RGMII; - break; case 10: - ugeth->ug_info->enet_interface = ENET_10_RGMII; +#ifdef CONFIG_PPC_MPC836x +/* FIXME: This code is for 100Mbs BUG fixing, +remove this lines when it will be fixed!!! */ + ugeth->ug_info->enet_interface = ENET_100_RGMII; + tempval = + (u32) mii_info->mdio_read(ugeth->dev, + mii_info->mii_id, + 0x1b); + tempval = (tempval & ~0x000f) | 0x000b; + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, 0x1b, + (u16) tempval); + tempval = + (u32) mii_info->mdio_read(ugeth->dev, + mii_info->mii_id, + MII_BMCR); + mii_info->mdio_write(ugeth->dev, + mii_info->mii_id, MII_BMCR, + (u16) (tempval | + BMCR_RESET)); + msleep(4000); +#endif /* CONFIG_MPC8360 */ + adjust_enet_interface(ugeth); break; default: ugeth_warn @@ -1723,7 +1785,6 @@ static void adjust_link(struct net_device *dev) dev->name, mii_info->speed); break; } - adjust_enet_interface(ugeth); ugeth_info("%s: Speed %dBT", dev->name, mii_info->speed); @@ -4072,7 +4133,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma static int mii_mng_configured = 0; const phandle *ph; const unsigned int *prop; - const void *mac_addr; ugeth_vdbg("%s: IN", __FUNCTION__); @@ -4198,12 +4258,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth->ug_info = ug_info; ugeth->dev = dev; - - mac_addr = get_property(np, "mac-address", NULL); - if (mac_addr == NULL) - mac_addr = get_property(np, "local-mac-address", NULL); - if (mac_addr) - memcpy(dev->dev_addr, mac_addr, 6); + memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6); return 0; } diff --git a/trunk/drivers/net/ucc_geth_phy.c b/trunk/drivers/net/ucc_geth_phy.c index 6fda6d88be49..3c86592ce03c 100644 --- a/trunk/drivers/net/ucc_geth_phy.c +++ b/trunk/drivers/net/ucc_geth_phy.c @@ -376,8 +376,6 @@ static int marvell_init(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); ucc_geth_phy_write(mii_info, 0x14, 0x0cd2); - ucc_geth_phy_write(mii_info, 0x1b, - (ucc_geth_phy_read(mii_info, 0x1b) & ~0x000f) | 0x000b); ucc_geth_phy_write(mii_info, MII_BMCR, ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET); msleep(4000); diff --git a/trunk/drivers/net/wan/pc300too.c b/trunk/drivers/net/wan/pc300too.c index bc156b51678a..79b2d5454d6b 100644 --- a/trunk/drivers/net/wan/pc300too.c +++ b/trunk/drivers/net/wan/pc300too.c @@ -101,8 +101,8 @@ typedef struct port_s { typedef struct card_s { int type; /* RSV, X21, etc. */ int n_ports; /* 1 or 2 ports */ - u8 __iomem *rambase; /* buffer memory base (virtual) */ - u8 __iomem *scabase; /* SCA memory base (virtual) */ + u8* __iomem rambase; /* buffer memory base (virtual) */ + u8* __iomem scabase; /* SCA memory base (virtual) */ plx9050 __iomem *plxbase; /* PLX registers memory base (virtual) */ u32 init_ctrl_value; /* Saved value - 9050 bug workaround */ u16 rx_ring_buffers; /* number of buffers in a ring */ @@ -134,7 +134,7 @@ typedef struct card_s { static void pc300_set_iface(port_t *port) { card_t *card = port->card; - u32 __iomem * init_ctrl = &card->plxbase->init_ctrl; + u32* init_ctrl = &card->plxbase->init_ctrl; u16 msci = get_msci(port); u8 rxs = port->rxs & CLK_BRG_MASK; u8 txs = port->txs & CLK_BRG_MASK; @@ -393,7 +393,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, /* PLX PCI 9050 workaround for local configuration register read bug */ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, scaphys); - card->init_ctrl_value = readl(&((plx9050 __iomem *)card->scabase)->init_ctrl); + card->init_ctrl_value = readl(&((plx9050*)card->scabase)->init_ctrl); pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, plxphys); /* Reset PLX */ @@ -519,10 +519,10 @@ static struct pci_device_id pc300_pci_tbl[] __devinitdata = { static struct pci_driver pc300_pci_driver = { - .name = "PC300", - .id_table = pc300_pci_tbl, - .probe = pc300_pci_init_one, - .remove = pc300_pci_remove_one, + name: "PC300", + id_table: pc300_pci_tbl, + probe: pc300_pci_init_one, + remove: pc300_pci_remove_one, }; diff --git a/trunk/drivers/net/wd.c b/trunk/drivers/net/wd.c index a0326818ff2f..7f38012b9c92 100644 --- a/trunk/drivers/net/wd.c +++ b/trunk/drivers/net/wd.c @@ -433,7 +433,7 @@ wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_ memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - memcpy_fromio(skb->data, xfer_start, count); + eth_io_copy_and_sum(skb, xfer_start, count, 0); } /* Turn off 16 bit access so that reboot works. ISA brain-damage */ diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index 4dbef0762376..bbf025874d0c 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -722,7 +722,7 @@ static int __init init_m32r_pcc(void) /* Set up interrupt handler(s) */ for (i = 0 ; i < pcc_sockets ; i++) { - socket[i].socket.dev.parent = &pcc_device.dev; + socket[i].socket.dev.dev = &pcc_device.dev; socket[i].socket.ops = &pcc_operations; socket[i].socket.resource_ops = &pccard_static_ops; socket[i].socket.owner = THIS_MODULE; diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 82f2ac87ccd4..94d3df62a5fa 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -305,7 +305,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, case RTC_IRQP_READ: if (ops->irq_set_freq) - err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); + err = put_user(rtc->irq_freq, (unsigned long *) arg); break; case RTC_IRQP_SET: diff --git a/trunk/drivers/s390/char/monreader.c b/trunk/drivers/s390/char/monreader.c index 3a1a958fb5f2..a138b1510093 100644 --- a/trunk/drivers/s390/char/monreader.c +++ b/trunk/drivers/s390/char/monreader.c @@ -3,7 +3,7 @@ * * Character device driver for reading z/VM *MONITOR service records. * - * Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH. * * Author: Gerald Schaefer */ @@ -22,7 +22,7 @@ #include #include #include -#include +#include "../net/iucv.h" //#define MON_DEBUG /* Debug messages on/off */ @@ -50,13 +50,14 @@ static char mon_dcss_name[9] = "MONDCSS\0"; struct mon_msg { u32 pos; u32 mca_offset; - struct iucv_message msg; + iucv_MessagePending local_eib; char msglim_reached; char replied_msglim; }; struct mon_private { - struct iucv_path *path; + u16 pathid; + iucv_handle_t iucv_handle; struct mon_msg *msg_array[MON_MSGLIM]; unsigned int write_index; unsigned int read_index; @@ -74,6 +75,8 @@ static unsigned long mon_dcss_end; static DECLARE_WAIT_QUEUE_HEAD(mon_read_wait_queue); static DECLARE_WAIT_QUEUE_HEAD(mon_conn_wait_queue); +static u8 iucv_host[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static u8 user_data_connect[16] = { /* Version code, must be 0x01 for shared mode */ 0x01, @@ -97,7 +100,8 @@ static u8 user_data_sever[16] = { * Create the 8 bytes EBCDIC DCSS segment name from * an ASCII name, incl. padding */ -static inline void dcss_mkname(char *ascii_name, char *ebcdic_name) +static inline void +dcss_mkname(char *ascii_name, char *ebcdic_name) { int i; @@ -115,7 +119,8 @@ static inline void dcss_mkname(char *ascii_name, char *ebcdic_name) * print appropriate error message for segment_load()/segment_type() * return code */ -static void mon_segment_warn(int rc, char* seg_name) +static void +mon_segment_warn(int rc, char* seg_name) { switch (rc) { case -ENOENT: @@ -161,37 +166,44 @@ static void mon_segment_warn(int rc, char* seg_name) } } -static inline unsigned long mon_mca_start(struct mon_msg *monmsg) +static inline unsigned long +mon_mca_start(struct mon_msg *monmsg) { - return *(u32 *) &monmsg->msg.rmmsg; + return monmsg->local_eib.ln1msg1.iprmmsg1_u32; } -static inline unsigned long mon_mca_end(struct mon_msg *monmsg) +static inline unsigned long +mon_mca_end(struct mon_msg *monmsg) { - return *(u32 *) &monmsg->msg.rmmsg[4]; + return monmsg->local_eib.ln1msg2.ipbfln1f; } -static inline u8 mon_mca_type(struct mon_msg *monmsg, u8 index) +static inline u8 +mon_mca_type(struct mon_msg *monmsg, u8 index) { return *((u8 *) mon_mca_start(monmsg) + monmsg->mca_offset + index); } -static inline u32 mon_mca_size(struct mon_msg *monmsg) +static inline u32 +mon_mca_size(struct mon_msg *monmsg) { return mon_mca_end(monmsg) - mon_mca_start(monmsg) + 1; } -static inline u32 mon_rec_start(struct mon_msg *monmsg) +static inline u32 +mon_rec_start(struct mon_msg *monmsg) { return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 4)); } -static inline u32 mon_rec_end(struct mon_msg *monmsg) +static inline u32 +mon_rec_end(struct mon_msg *monmsg) { return *((u32 *) (mon_mca_start(monmsg) + monmsg->mca_offset + 8)); } -static inline int mon_check_mca(struct mon_msg *monmsg) +static inline int +mon_check_mca(struct mon_msg *monmsg) { if ((mon_rec_end(monmsg) <= mon_rec_start(monmsg)) || (mon_rec_start(monmsg) < mon_dcss_start) || @@ -209,17 +221,20 @@ static inline int mon_check_mca(struct mon_msg *monmsg) return 0; } -static inline int mon_send_reply(struct mon_msg *monmsg, - struct mon_private *monpriv) +static inline int +mon_send_reply(struct mon_msg *monmsg, struct mon_private *monpriv) { + u8 prmmsg[8]; int rc; P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = " "0x%08X\n\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); - - rc = iucv_message_reply(monpriv->path, &monmsg->msg, - IUCV_IPRMDATA, NULL, 0); + monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls); + rc = iucv_reply_prmmsg(monmsg->local_eib.ippathid, + monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls, + 0, prmmsg); atomic_dec(&monpriv->msglim_count); if (likely(!monmsg->msglim_reached)) { monmsg->pos = 0; @@ -236,19 +251,10 @@ static inline int mon_send_reply(struct mon_msg *monmsg, return 0; } -static inline void mon_free_mem(struct mon_private *monpriv) -{ - int i; - - for (i = 0; i < MON_MSGLIM; i++) - if (monpriv->msg_array[i]) - kfree(monpriv->msg_array[i]); - kfree(monpriv); -} - -static inline struct mon_private *mon_alloc_mem(void) +static inline struct mon_private * +mon_alloc_mem(void) { - int i; + int i,j; struct mon_private *monpriv; monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); @@ -261,15 +267,16 @@ static inline struct mon_private *mon_alloc_mem(void) GFP_KERNEL); if (!monpriv->msg_array[i]) { P_ERROR("open, no memory for msg_array\n"); - mon_free_mem(monpriv); + for (j = 0; j < i; j++) + kfree(monpriv->msg_array[j]); return NULL; } } return monpriv; } -static inline void mon_read_debug(struct mon_msg *monmsg, - struct mon_private *monpriv) +static inline void +mon_read_debug(struct mon_msg *monmsg, struct mon_private *monpriv) { #ifdef MON_DEBUG u8 msg_type[2], mca_type; @@ -277,7 +284,7 @@ static inline void mon_read_debug(struct mon_msg *monmsg, records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1; - memcpy(msg_type, &monmsg->msg.class, 2); + memcpy(msg_type, &monmsg->local_eib.iptrgcls, 2); EBCASC(msg_type, 2); mca_type = mon_mca_type(monmsg, 0); EBCASC(&mca_type, 1); @@ -285,7 +292,8 @@ static inline void mon_read_debug(struct mon_msg *monmsg, P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n", monpriv->read_index, monpriv->write_index); P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n", - monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class); + monmsg->local_eib.ippathid, monmsg->local_eib.ipmsgid, + monmsg->local_eib.iptrgcls); P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n", msg_type[0], msg_type[1], mca_type ? mca_type : 'X', mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2)); @@ -298,7 +306,8 @@ static inline void mon_read_debug(struct mon_msg *monmsg, #endif } -static inline void mon_next_mca(struct mon_msg *monmsg) +static inline void +mon_next_mca(struct mon_msg *monmsg) { if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12)) return; @@ -307,7 +316,8 @@ static inline void mon_next_mca(struct mon_msg *monmsg) monmsg->pos = 0; } -static inline struct mon_msg *mon_next_message(struct mon_private *monpriv) +static inline struct mon_msg * +mon_next_message(struct mon_private *monpriv) { struct mon_msg *monmsg; @@ -332,37 +342,39 @@ static inline struct mon_msg *mon_next_message(struct mon_private *monpriv) /****************************************************************************** * IUCV handler * *****************************************************************************/ -static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) +static void +mon_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; P_DEBUG("IUCV connection completed\n"); P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = " "0x%02X, Sample = 0x%02X\n", - ipuser[0], ipuser[1], ipuser[2]); + eib->ipuser[0], eib->ipuser[1], eib->ipuser[2]); atomic_set(&monpriv->iucv_connected, 1); wake_up(&mon_conn_wait_queue); } -static void mon_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) +static void +mon_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; - P_ERROR("IUCV connection severed with rc = 0x%X\n", ipuser[0]); - iucv_path_sever(path, NULL); + P_ERROR("IUCV connection severed with rc = 0x%X\n", + (u8) eib->ipuser[0]); atomic_set(&monpriv->iucv_severed, 1); wake_up(&mon_conn_wait_queue); wake_up_interruptible(&mon_read_wait_queue); } -static void mon_iucv_message_pending(struct iucv_path *path, - struct iucv_message *msg) +static void +mon_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data) { - struct mon_private *monpriv = path->private; + struct mon_private *monpriv = (struct mon_private *) pgm_data; P_DEBUG("IUCV message pending\n"); - memcpy(&monpriv->msg_array[monpriv->write_index]->msg, - msg, sizeof(*msg)); + memcpy(&monpriv->msg_array[monpriv->write_index]->local_eib, eib, + sizeof(iucv_MessagePending)); if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) { P_WARNING("IUCV message pending, message limit (%i) reached\n", MON_MSGLIM); @@ -373,45 +385,54 @@ static void mon_iucv_message_pending(struct iucv_path *path, wake_up_interruptible(&mon_read_wait_queue); } -static struct iucv_handler monreader_iucv_handler = { - .path_complete = mon_iucv_path_complete, - .path_severed = mon_iucv_path_severed, - .message_pending = mon_iucv_message_pending, +static iucv_interrupt_ops_t mon_iucvops = { + .ConnectionComplete = mon_iucv_ConnectionComplete, + .ConnectionSevered = mon_iucv_ConnectionSevered, + .MessagePending = mon_iucv_MessagePending, }; /****************************************************************************** * file operations * *****************************************************************************/ -static int mon_open(struct inode *inode, struct file *filp) +static int +mon_open(struct inode *inode, struct file *filp) { + int rc, i; struct mon_private *monpriv; - int rc; /* * only one user allowed */ - rc = -EBUSY; if (test_and_set_bit(MON_IN_USE, &mon_in_use)) - goto out; + return -EBUSY; - rc = -ENOMEM; monpriv = mon_alloc_mem(); if (!monpriv) - goto out_use; + return -ENOMEM; /* - * Connect to *MONITOR service + * Register with IUCV and connect to *MONITOR service */ - monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL); - if (!monpriv->path) - goto out_priv; - rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler, - MON_SERVICE, NULL, user_data_connect, monpriv); + monpriv->iucv_handle = iucv_register_program("my_monreader ", + MON_SERVICE, + NULL, + &mon_iucvops, + monpriv); + if (!monpriv->iucv_handle) { + P_ERROR("failed to register with iucv driver\n"); + rc = -EIO; + goto out_error; + } + P_INFO("open, registered with IUCV\n"); + + rc = iucv_connect(&monpriv->pathid, MON_MSGLIM, user_data_connect, + MON_SERVICE, iucv_host, IPRMDATA, NULL, NULL, + monpriv->iucv_handle, NULL); if (rc) { P_ERROR("iucv connection to *MONITOR failed with " "IPUSER SEVER code = %i\n", rc); rc = -EIO; - goto out_path; + goto out_unregister; } /* * Wait for connection confirmation @@ -423,23 +444,24 @@ static int mon_open(struct inode *inode, struct file *filp) atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); rc = -EIO; - goto out_path; + goto out_unregister; } P_INFO("open, established connection to *MONITOR service\n\n"); filp->private_data = monpriv; return nonseekable_open(inode, filp); -out_path: - kfree(monpriv->path); -out_priv: - mon_free_mem(monpriv); -out_use: +out_unregister: + iucv_unregister_program(monpriv->iucv_handle); +out_error: + for (i = 0; i < MON_MSGLIM; i++) + kfree(monpriv->msg_array[i]); + kfree(monpriv); clear_bit(MON_IN_USE, &mon_in_use); -out: return rc; } -static int mon_close(struct inode *inode, struct file *filp) +static int +mon_close(struct inode *inode, struct file *filp) { int rc, i; struct mon_private *monpriv = filp->private_data; @@ -447,12 +469,18 @@ static int mon_close(struct inode *inode, struct file *filp) /* * Close IUCV connection and unregister */ - rc = iucv_path_sever(monpriv->path, user_data_sever); + rc = iucv_sever(monpriv->pathid, user_data_sever); if (rc) P_ERROR("close, iucv_sever failed with rc = %i\n", rc); else P_INFO("close, terminated connection to *MONITOR service\n"); + rc = iucv_unregister_program(monpriv->iucv_handle); + if (rc) + P_ERROR("close, iucv_unregister failed with rc = %i\n", rc); + else + P_INFO("close, unregistered with IUCV\n"); + atomic_set(&monpriv->iucv_severed, 0); atomic_set(&monpriv->iucv_connected, 0); atomic_set(&monpriv->read_ready, 0); @@ -467,8 +495,8 @@ static int mon_close(struct inode *inode, struct file *filp) return 0; } -static ssize_t mon_read(struct file *filp, char __user *data, - size_t count, loff_t *ppos) +static ssize_t +mon_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) { struct mon_private *monpriv = filp->private_data; struct mon_msg *monmsg; @@ -535,7 +563,8 @@ static ssize_t mon_read(struct file *filp, char __user *data, return count; } -static unsigned int mon_poll(struct file *filp, struct poll_table_struct *p) +static unsigned int +mon_poll(struct file *filp, struct poll_table_struct *p) { struct mon_private *monpriv = filp->private_data; @@ -564,7 +593,8 @@ static struct miscdevice mon_dev = { /****************************************************************************** * module init/exit * *****************************************************************************/ -static int __init mon_init(void) +static int __init +mon_init(void) { int rc; @@ -573,34 +603,22 @@ static int __init mon_init(void) return -ENODEV; } - /* - * Register with IUCV and connect to *MONITOR service - */ - rc = iucv_register(&monreader_iucv_handler, 1); - if (rc) { - P_ERROR("failed to register with iucv driver\n"); - return rc; - } - P_INFO("open, registered with IUCV\n"); - rc = segment_type(mon_dcss_name); if (rc < 0) { mon_segment_warn(rc, mon_dcss_name); - goto out_iucv; + return rc; } if (rc != SEG_TYPE_SC) { P_ERROR("segment %s has unsupported type, should be SC\n", mon_dcss_name); - rc = -EINVAL; - goto out_iucv; + return -EINVAL; } rc = segment_load(mon_dcss_name, SEGMENT_SHARED, &mon_dcss_start, &mon_dcss_end); if (rc < 0) { mon_segment_warn(rc, mon_dcss_name); - rc = -EINVAL; - goto out_iucv; + return -EINVAL; } dcss_mkname(mon_dcss_name, &user_data_connect[8]); @@ -616,16 +634,14 @@ static int __init mon_init(void) out: segment_unload(mon_dcss_name); -out_iucv: - iucv_unregister(&monreader_iucv_handler, 1); return rc; } -static void __exit mon_exit(void) +static void __exit +mon_exit(void) { segment_unload(mon_dcss_name); WARN_ON(misc_deregister(&mon_dev) != 0); - iucv_unregister(&monreader_iucv_handler, 1); return; } diff --git a/trunk/drivers/s390/char/vmlogrdr.c b/trunk/drivers/s390/char/vmlogrdr.c index 8432a76b961e..4f894dc2373b 100644 --- a/trunk/drivers/s390/char/vmlogrdr.c +++ b/trunk/drivers/s390/char/vmlogrdr.c @@ -3,7 +3,7 @@ * character device driver for reading z/VM system service records * * - * Copyright 2004 IBM Corporation + * Copyright (C) 2004 IBM Corporation * character device driver for reading z/VM system service records, * Version 1.0 * Author(s): Xenia Tkatschow @@ -21,7 +21,7 @@ #include #include #include -#include +#include "../net/iucv.h" #include #include #include @@ -60,11 +60,12 @@ struct vmlogrdr_priv_t { char system_service[8]; char internal_name[8]; char recording_name[8]; - struct iucv_path *path; + u16 pathid; int connection_established; int iucv_path_severed; - struct iucv_message local_interrupt_buffer; + iucv_MessagePending local_interrupt_buffer; atomic_t receive_ready; + iucv_handle_t iucv_handle; int minor_num; char * buffer; char * current_position; @@ -96,19 +97,37 @@ static struct file_operations vmlogrdr_fops = { }; -static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]); -static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]); -static void vmlogrdr_iucv_message_pending(struct iucv_path *, - struct iucv_message *); +static u8 iucvMagic[16] = { + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 +}; -static struct iucv_handler vmlogrdr_iucv_handler = { - .path_complete = vmlogrdr_iucv_path_complete, - .path_severed = vmlogrdr_iucv_path_severed, - .message_pending = vmlogrdr_iucv_message_pending, +static u8 mask[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +static void +vmlogrdr_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data); +static void +vmlogrdr_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data); +static void +vmlogrdr_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data); + + +static iucv_interrupt_ops_t vmlogrdr_iucvops = { + .ConnectionComplete = vmlogrdr_iucv_ConnectionComplete, + .ConnectionSevered = vmlogrdr_iucv_ConnectionSevered, + .MessagePending = vmlogrdr_iucv_MessagePending, +}; + static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue); static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue); @@ -157,29 +176,28 @@ static struct cdev *vmlogrdr_cdev = NULL; static int recording_class_AB; -static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) +static void +vmlogrdr_iucv_ConnectionComplete (iucv_ConnectionComplete * eib, + void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; - + struct vmlogrdr_priv_t * logptr = pgm_data; spin_lock(&logptr->priv_lock); logptr->connection_established = 1; spin_unlock(&logptr->priv_lock); wake_up(&conn_wait_queue); + return; } -static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) +static void +vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; - u8 reason = (u8) ipuser[8]; + u8 reason = (u8) eib->ipuser[8]; + struct vmlogrdr_priv_t * logptr = pgm_data; printk (KERN_ERR "vmlogrdr: connection severed with" " reason %i\n", reason); - iucv_path_sever(path, NULL); - kfree(path); - logptr->path = NULL; - spin_lock(&logptr->priv_lock); logptr->connection_established = 0; logptr->iucv_path_severed = 1; @@ -191,10 +209,10 @@ static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) } -static void vmlogrdr_iucv_message_pending(struct iucv_path *path, - struct iucv_message *msg) +static void +vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data) { - struct vmlogrdr_priv_t * logptr = path->private; + struct vmlogrdr_priv_t * logptr = pgm_data; /* * This function is the bottom half so it should be quick. @@ -202,15 +220,15 @@ static void vmlogrdr_iucv_message_pending(struct iucv_path *path, * the usage count */ spin_lock(&logptr->priv_lock); - memcpy(&logptr->local_interrupt_buffer, msg, sizeof(*msg)); + memcpy(&(logptr->local_interrupt_buffer), eib, sizeof(*eib)); atomic_inc(&logptr->receive_ready); spin_unlock(&logptr->priv_lock); wake_up_interruptible(&read_wait_queue); } -static int vmlogrdr_get_recording_class_AB(void) -{ +static int +vmlogrdr_get_recording_class_AB(void) { char cp_command[]="QUERY COMMAND RECORDING "; char cp_response[80]; char *tail; @@ -240,9 +258,8 @@ static int vmlogrdr_get_recording_class_AB(void) } -static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, - int action, int purge) -{ +static int +vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) { char cp_command[80]; char cp_response[160]; @@ -300,7 +317,8 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, } -static int vmlogrdr_open (struct inode *inode, struct file *filp) +static int +vmlogrdr_open (struct inode *inode, struct file *filp) { int dev_num = 0; struct vmlogrdr_priv_t * logptr = NULL; @@ -310,7 +328,10 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) dev_num = iminor(inode); if (dev_num > MAXMINOR) return -ENODEV; + logptr = &sys_ser[dev_num]; + if (logptr == NULL) + return -ENODEV; /* * only allow for blocking reads to be open @@ -323,38 +344,52 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) if (logptr->dev_in_use) { spin_unlock_bh(&logptr->priv_lock); return -EBUSY; + } else { + logptr->dev_in_use = 1; + spin_unlock_bh(&logptr->priv_lock); } - logptr->dev_in_use = 1; - logptr->connection_established = 0; - logptr->iucv_path_severed = 0; + atomic_set(&logptr->receive_ready, 0); logptr->buffer_free = 1; - spin_unlock_bh(&logptr->priv_lock); /* set the file options */ filp->private_data = logptr; filp->f_op = &vmlogrdr_fops; /* start recording for this service*/ - if (logptr->autorecording) { + ret=0; + if (logptr->autorecording) ret = vmlogrdr_recording(logptr,1,logptr->autopurge); - if (ret) - printk (KERN_WARNING "vmlogrdr: failed to start " - "recording automatically\n"); + if (ret) + printk (KERN_WARNING "vmlogrdr: failed to start " + "recording automatically\n"); + + /* Register with iucv driver */ + logptr->iucv_handle = iucv_register_program(iucvMagic, + logptr->system_service, mask, &vmlogrdr_iucvops, + logptr); + + if (logptr->iucv_handle == NULL) { + printk (KERN_ERR "vmlogrdr: failed to register with" + "iucv driver\n"); + goto not_registered; } /* create connection to the system service */ - logptr->path = iucv_path_alloc(10, 0, GFP_KERNEL); - if (!logptr->path) - goto out_dev; - connect_rc = iucv_path_connect(logptr->path, &vmlogrdr_iucv_handler, - logptr->system_service, NULL, NULL, - logptr); + spin_lock_bh(&logptr->priv_lock); + logptr->connection_established = 0; + logptr->iucv_path_severed = 0; + spin_unlock_bh(&logptr->priv_lock); + + connect_rc = iucv_connect (&(logptr->pathid), 10, iucvMagic, + logptr->system_service, iucv_host, 0, + NULL, NULL, + logptr->iucv_handle, NULL); if (connect_rc) { printk (KERN_ERR "vmlogrdr: iucv connection to %s " "failed with rc %i \n", logptr->system_service, connect_rc); - goto out_path; + goto not_connected; } /* We've issued the connect and now we must wait for a @@ -363,28 +398,35 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) */ wait_event(conn_wait_queue, (logptr->connection_established) || (logptr->iucv_path_severed)); - if (logptr->iucv_path_severed) - goto out_record; + if (logptr->iucv_path_severed) { + goto not_connected; + } + return nonseekable_open(inode, filp); -out_record: +not_connected: + iucv_unregister_program(logptr->iucv_handle); + logptr->iucv_handle = NULL; +not_registered: if (logptr->autorecording) vmlogrdr_recording(logptr,0,logptr->autopurge); -out_path: - kfree(logptr->path); /* kfree(NULL) is ok. */ - logptr->path = NULL; -out_dev: logptr->dev_in_use = 0; return -EIO; + + } -static int vmlogrdr_release (struct inode *inode, struct file *filp) +static int +vmlogrdr_release (struct inode *inode, struct file *filp) { int ret; struct vmlogrdr_priv_t * logptr = filp->private_data; + iucv_unregister_program(logptr->iucv_handle); + logptr->iucv_handle = NULL; + if (logptr->autorecording) { ret = vmlogrdr_recording(logptr,0,logptr->autopurge); if (ret) @@ -397,8 +439,8 @@ static int vmlogrdr_release (struct inode *inode, struct file *filp) } -static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) -{ +static int +vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) { int rc, *temp; /* we need to keep track of two data sizes here: * The number of bytes we need to receive from iucv and @@ -419,7 +461,8 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) * We need to return the total length of the record * + size of FENCE in the first 4 bytes of the buffer. */ - iucv_data_count = priv->local_interrupt_buffer.length; + iucv_data_count = + priv->local_interrupt_buffer.ln1msg2.ipbfln1f; user_data_count = sizeof(int); temp = (int*)priv->buffer; *temp= iucv_data_count + sizeof(FENCE); @@ -431,10 +474,14 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) */ if (iucv_data_count > NET_BUFFER_SIZE) iucv_data_count = NET_BUFFER_SIZE; - rc = iucv_message_receive(priv->path, - &priv->local_interrupt_buffer, - 0, buffer, iucv_data_count, - &priv->residual_length); + rc = iucv_receive(priv->pathid, + priv->local_interrupt_buffer.ipmsgid, + priv->local_interrupt_buffer.iptrgcls, + buffer, + iucv_data_count, + NULL, + NULL, + &priv->residual_length); spin_unlock_bh(&priv->priv_lock); /* An rc of 5 indicates that the record was bigger then * the buffer, which is OK for us. A 9 indicates that the @@ -466,8 +513,8 @@ static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) } -static ssize_t vmlogrdr_read(struct file *filp, char __user *data, - size_t count, loff_t * ppos) +static ssize_t +vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos) { int rc; struct vmlogrdr_priv_t * priv = filp->private_data; @@ -499,10 +546,8 @@ static ssize_t vmlogrdr_read(struct file *filp, char __user *data, return count; } -static ssize_t vmlogrdr_autopurge_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret = count; @@ -520,10 +565,8 @@ static ssize_t vmlogrdr_autopurge_store(struct device * dev, } -static ssize_t vmlogrdr_autopurge_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ +static ssize_t +vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vmlogrdr_priv_t *priv = dev->driver_data; return sprintf(buf, "%u\n", priv->autopurge); } @@ -533,10 +576,8 @@ static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show, vmlogrdr_autopurge_store); -static ssize_t vmlogrdr_purge_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { char cp_command[80]; char cp_response[80]; @@ -576,10 +617,9 @@ static ssize_t vmlogrdr_purge_store(struct device * dev, static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store); -static ssize_t vmlogrdr_autorecording_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ +static ssize_t +vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) { struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret = count; @@ -597,10 +637,8 @@ static ssize_t vmlogrdr_autorecording_store(struct device *dev, } -static ssize_t vmlogrdr_autorecording_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ +static ssize_t +vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vmlogrdr_priv_t *priv = dev->driver_data; return sprintf(buf, "%u\n", priv->autorecording); } @@ -610,10 +648,9 @@ static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show, vmlogrdr_autorecording_store); -static ssize_t vmlogrdr_recording_store(struct device * dev, - struct device_attribute *attr, - const char * buf, size_t count) -{ +static ssize_t +vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) { + struct vmlogrdr_priv_t *priv = dev->driver_data; ssize_t ret; @@ -638,9 +675,8 @@ static ssize_t vmlogrdr_recording_store(struct device * dev, static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store); -static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, - char *buf) -{ +static ssize_t +vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) { char cp_command[] = "QUERY RECORDING "; int len; @@ -673,63 +709,52 @@ static struct device_driver vmlogrdr_driver = { }; -static int vmlogrdr_register_driver(void) -{ +static int +vmlogrdr_register_driver(void) { int ret; - /* Register with iucv driver */ - ret = iucv_register(&vmlogrdr_iucv_handler, 1); - if (ret) { - printk (KERN_ERR "vmlogrdr: failed to register with" - "iucv driver\n"); - goto out; - } - ret = driver_register(&vmlogrdr_driver); if (ret) { printk(KERN_ERR "vmlogrdr: failed to register driver.\n"); - goto out_iucv; + return ret; } ret = driver_create_file(&vmlogrdr_driver, &driver_attr_recording_status); if (ret) { printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n"); - goto out_driver; + goto unregdriver; } vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); if (IS_ERR(vmlogrdr_class)) { printk(KERN_ERR "vmlogrdr: failed to create class.\n"); - ret = PTR_ERR(vmlogrdr_class); - vmlogrdr_class = NULL; - goto out_attr; + ret=PTR_ERR(vmlogrdr_class); + vmlogrdr_class=NULL; + goto unregattr; } return 0; -out_attr: +unregattr: driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); -out_driver: +unregdriver: driver_unregister(&vmlogrdr_driver); -out_iucv: - iucv_unregister(&vmlogrdr_iucv_handler, 1); -out: return ret; } -static void vmlogrdr_unregister_driver(void) -{ +static void +vmlogrdr_unregister_driver(void) { class_destroy(vmlogrdr_class); vmlogrdr_class = NULL; driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); driver_unregister(&vmlogrdr_driver); - iucv_unregister(&vmlogrdr_iucv_handler, 1); + return; } -static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) -{ +static int +vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) { struct device *dev; int ret; @@ -778,10 +803,9 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) } -static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) -{ - class_device_destroy(vmlogrdr_class, - MKDEV(vmlogrdr_major, priv->minor_num)); +static int +vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) { + class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num)); if (priv->device != NULL) { sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); device_unregister(priv->device); @@ -791,8 +815,8 @@ static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) } -static int vmlogrdr_register_cdev(dev_t dev) -{ +static int +vmlogrdr_register_cdev(dev_t dev) { int rc = 0; vmlogrdr_cdev = cdev_alloc(); if (!vmlogrdr_cdev) { @@ -812,10 +836,9 @@ static int vmlogrdr_register_cdev(dev_t dev) } -static void vmlogrdr_cleanup(void) -{ +static void +vmlogrdr_cleanup(void) { int i; - if (vmlogrdr_cdev) { cdev_del(vmlogrdr_cdev); vmlogrdr_cdev=NULL; @@ -832,7 +855,8 @@ static void vmlogrdr_cleanup(void) } -static int vmlogrdr_init(void) +static int +vmlogrdr_init(void) { int rc; int i; @@ -882,7 +906,8 @@ static int vmlogrdr_init(void) } -static void vmlogrdr_exit(void) +static void +vmlogrdr_exit(void) { vmlogrdr_cleanup(); printk (KERN_INFO "vmlogrdr: driver unloaded\n"); diff --git a/trunk/drivers/s390/net/Kconfig b/trunk/drivers/s390/net/Kconfig index f98fa465df0a..52625153a4f0 100644 --- a/trunk/drivers/s390/net/Kconfig +++ b/trunk/drivers/s390/net/Kconfig @@ -22,6 +22,13 @@ config CTC available. This option is also available as a module which will be called ctc.ko. If you do not know what it is, it's safe to say "Y". +config IUCV + tristate "IUCV support (VM only)" + help + Select this option if you want to use inter-user communication + under VM or VIF. If unsure, say "Y" to enable a fast communication + link between VM guests. + config NETIUCV tristate "IUCV network device support (VM only)" depends on IUCV && NETDEVICES diff --git a/trunk/drivers/s390/net/Makefile b/trunk/drivers/s390/net/Makefile index bbe3ab2e93d9..4777e36a922f 100644 --- a/trunk/drivers/s390/net/Makefile +++ b/trunk/drivers/s390/net/Makefile @@ -4,6 +4,7 @@ ctc-objs := ctcmain.o ctcdbug.o +obj-$(CONFIG_IUCV) += iucv.o obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o diff --git a/trunk/drivers/s390/net/iucv.c b/trunk/drivers/s390/net/iucv.c new file mode 100644 index 000000000000..229aeb5fc399 --- /dev/null +++ b/trunk/drivers/s390/net/iucv.c @@ -0,0 +1,2540 @@ +/* + * IUCV network driver + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): + * Original source: + * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 + * Xenia Tkatschow (xenia@us.ibm.com) + * 2Gb awareness and general cleanup: + * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + * + * Documentation used: + * The original source + * CP Programming Service, IBM document # SC24-5760 + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* #define DEBUG */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iucv.h" +#include +#include +#include +#include +#include + +/* FLAGS: + * All flags are defined in the field IPFLAGS1 of each function + * and can be found in CP Programming Services. + * IPSRCCLS - Indicates you have specified a source class + * IPFGMCL - Indicates you have specified a target class + * IPFGPID - Indicates you have specified a pathid + * IPFGMID - Indicates you have specified a message ID + * IPANSLST - Indicates that you are using an address list for + * reply data + * IPBUFLST - Indicates that you are using an address list for + * message data + */ + +#define IPSRCCLS 0x01 +#define IPFGMCL 0x01 +#define IPFGPID 0x02 +#define IPFGMID 0x04 +#define IPANSLST 0x08 +#define IPBUFLST 0x40 + +static int +iucv_bus_match (struct device *dev, struct device_driver *drv) +{ + return 0; +} + +struct bus_type iucv_bus = { + .name = "iucv", + .match = iucv_bus_match, +}; + +struct device *iucv_root; + +/* General IUCV interrupt structure */ +typedef struct { + __u16 ippathid; + __u8 res1; + __u8 iptype; + __u32 res2; + __u8 ipvmid[8]; + __u8 res3[24]; +} iucv_GeneralInterrupt; + +static iucv_GeneralInterrupt *iucv_external_int_buffer = NULL; + +/* Spin Lock declaration */ + +static DEFINE_SPINLOCK(iucv_lock); + +static int messagesDisabled = 0; + +/***************INTERRUPT HANDLING ***************/ + +typedef struct { + struct list_head queue; + iucv_GeneralInterrupt data; +} iucv_irqdata; + +static struct list_head iucv_irq_queue; +static DEFINE_SPINLOCK(iucv_irq_queue_lock); + +/* + *Internal function prototypes + */ +static void iucv_tasklet_handler(unsigned long); +static void iucv_irq_handler(__u16); + +static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0); + +/************ FUNCTION ID'S ****************************/ + +#define ACCEPT 10 +#define CONNECT 11 +#define DECLARE_BUFFER 12 +#define PURGE 9 +#define QUERY 0 +#define QUIESCE 13 +#define RECEIVE 5 +#define REJECT 8 +#define REPLY 6 +#define RESUME 14 +#define RETRIEVE_BUFFER 2 +#define SEND 4 +#define SETMASK 16 +#define SEVER 15 + +/** + * Structure: handler + * members: list - list management. + * structure: id + * userid - 8 char array of machine identification + * user_data - 16 char array for user identification + * mask - 24 char array used to compare the 2 previous + * interrupt_table - vector of interrupt functions. + * pgm_data - ulong, application data that is passed + * to the interrupt handlers +*/ +typedef struct handler_t { + struct list_head list; + struct { + __u8 userid[8]; + __u8 user_data[16]; + __u8 mask[24]; + } id; + iucv_interrupt_ops_t *interrupt_table; + void *pgm_data; +} handler; + +/** + * iucv_handler_table: List of registered handlers. + */ +static struct list_head iucv_handler_table; + +/** + * iucv_pathid_table: an array of *handler pointing into + * iucv_handler_table for fast indexing by pathid; + */ +static handler **iucv_pathid_table; + +static unsigned long max_connections; + +/** + * iucv_cpuid: contains the logical cpu number of the cpu which + * has declared the iucv buffer by issuing DECLARE_BUFFER. + * If no cpu has done the initialization iucv_cpuid contains -1. + */ +static int iucv_cpuid = -1; +/** + * register_flag: is 0 when external interrupt has not been registered + */ +static int register_flag; + +/****************FIVE 40-BYTE PARAMETER STRUCTURES******************/ +/* Data struct 1: iparml_control + * Used for iucv_accept + * iucv_connect + * iucv_quiesce + * iucv_resume + * iucv_sever + * iucv_retrieve_buffer + * Data struct 2: iparml_dpl (data in parameter list) + * Used for iucv_send_prmmsg + * iucv_send2way_prmmsg + * iucv_send2way_prmmsg_array + * iucv_reply_prmmsg + * Data struct 3: iparml_db (data in a buffer) + * Used for iucv_receive + * iucv_receive_array + * iucv_reject + * iucv_reply + * iucv_reply_array + * iucv_send + * iucv_send_array + * iucv_send2way + * iucv_send2way_array + * iucv_declare_buffer + * Data struct 4: iparml_purge + * Used for iucv_purge + * iucv_query + * Data struct 5: iparml_set_mask + * Used for iucv_set_mask + */ + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u16 ipmsglim; + __u16 res1; + __u8 ipvmid[8]; + __u8 ipuser[16]; + __u8 iptarget[8]; +} iparml_control; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u8 iprmmsg[8]; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; +} iparml_dpl; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u32 iptrgcls; + __u32 ipbfadr1; + __u32 ipbfln1f; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 ipbfadr2; + __u32 ipbfln2f; + __u32 res; +} iparml_db; + +typedef struct { + __u16 ippathid; + __u8 ipflags1; + __u8 iprcode; + __u32 ipmsgid; + __u8 ipaudit[3]; + __u8 res1[5]; + __u32 res2; + __u32 ipsrccls; + __u32 ipmsgtag; + __u32 res3[3]; +} iparml_purge; + +typedef struct { + __u8 ipmask; + __u8 res1[2]; + __u8 iprcode; + __u32 res2[9]; +} iparml_set_mask; + +typedef struct { + union { + iparml_control p_ctrl; + iparml_dpl p_dpl; + iparml_db p_db; + iparml_purge p_purge; + iparml_set_mask p_set_mask; + } param; + atomic_t in_use; + __u32 res; +} __attribute__ ((aligned(8))) iucv_param; +#define PARAM_POOL_SIZE (PAGE_SIZE / sizeof(iucv_param)) + +static iucv_param * iucv_param_pool; + +MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); +MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver"); +MODULE_LICENSE("GPL"); + +/* + * Debugging stuff + *******************************************************************************/ + + +#ifdef DEBUG +static int debuglevel = 0; + +module_param(debuglevel, int, 0); +MODULE_PARM_DESC(debuglevel, + "Specifies the debug level (0=off ... 3=all)"); + +static void +iucv_dumpit(char *title, void *buf, int len) +{ + int i; + __u8 *p = (__u8 *)buf; + + if (debuglevel < 3) + return; + + printk(KERN_DEBUG "%s\n", title); + printk(" "); + for (i = 0; i < len; i++) { + if (!(i % 16) && i != 0) + printk ("\n "); + else if (!(i % 4) && i != 0) + printk(" "); + printk("%02X", *p++); + } + if (len % 16) + printk ("\n"); + return; +} +#define iucv_debug(lvl, fmt, args...) \ +do { \ + if (debuglevel >= lvl) \ + printk(KERN_DEBUG "%s: " fmt "\n", __FUNCTION__ , ## args); \ +} while (0) + +#else + +#define iucv_debug(lvl, fmt, args...) do { } while (0) +#define iucv_dumpit(title, buf, len) do { } while (0) + +#endif + +/* + * Internal functions + *******************************************************************************/ + +/** + * print start banner + */ +static void +iucv_banner(void) +{ + printk(KERN_INFO "IUCV lowlevel driver initialized\n"); +} + +/** + * iucv_init - Initialization + * + * Allocates and initializes various data structures. + */ +static int +iucv_init(void) +{ + int ret; + + if (iucv_external_int_buffer) + return 0; + + if (!MACHINE_IS_VM) { + printk(KERN_ERR "IUCV: IUCV connection needs VM as base\n"); + return -EPROTONOSUPPORT; + } + + ret = bus_register(&iucv_bus); + if (ret) { + printk(KERN_ERR "IUCV: failed to register bus.\n"); + return ret; + } + + iucv_root = s390_root_dev_register("iucv"); + if (IS_ERR(iucv_root)) { + printk(KERN_ERR "IUCV: failed to register iucv root.\n"); + bus_unregister(&iucv_bus); + return PTR_ERR(iucv_root); + } + + /* Note: GFP_DMA used used to get memory below 2G */ + iucv_external_int_buffer = kzalloc(sizeof(iucv_GeneralInterrupt), + GFP_KERNEL|GFP_DMA); + if (!iucv_external_int_buffer) { + printk(KERN_WARNING + "%s: Could not allocate external interrupt buffer\n", + __FUNCTION__); + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + return -ENOMEM; + } + + /* Initialize parameter pool */ + iucv_param_pool = kzalloc(sizeof(iucv_param) * PARAM_POOL_SIZE, + GFP_KERNEL|GFP_DMA); + if (!iucv_param_pool) { + printk(KERN_WARNING "%s: Could not allocate param pool\n", + __FUNCTION__); + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + return -ENOMEM; + } + + /* Initialize irq queue */ + INIT_LIST_HEAD(&iucv_irq_queue); + + /* Initialize handler table */ + INIT_LIST_HEAD(&iucv_handler_table); + + iucv_banner(); + return 0; +} + +/** + * iucv_exit - De-Initialization + * + * Frees everything allocated from iucv_init. + */ +static int iucv_retrieve_buffer (void); + +static void +iucv_exit(void) +{ + iucv_retrieve_buffer(); + kfree(iucv_external_int_buffer); + iucv_external_int_buffer = NULL; + kfree(iucv_param_pool); + iucv_param_pool = NULL; + s390_root_dev_unregister(iucv_root); + bus_unregister(&iucv_bus); + printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); +} + +/** + * grab_param: - Get a parameter buffer from the pre-allocated pool. + * + * This function searches for an unused element in the pre-allocated pool + * of parameter buffers. If one is found, it marks it "in use" and returns + * a pointer to it. The calling function is responsible for releasing it + * when it has finished its usage. + * + * Returns: A pointer to iucv_param. + */ +static __inline__ iucv_param * +grab_param(void) +{ + iucv_param *ptr; + static int hint = 0; + + ptr = iucv_param_pool + hint; + do { + ptr++; + if (ptr >= iucv_param_pool + PARAM_POOL_SIZE) + ptr = iucv_param_pool; + } while (atomic_cmpxchg(&ptr->in_use, 0, 1) != 0); + hint = ptr - iucv_param_pool; + + memset(&ptr->param, 0, sizeof(ptr->param)); + return ptr; +} + +/** + * release_param - Release a parameter buffer. + * @p: A pointer to a struct iucv_param, previously obtained by calling + * grab_param(). + * + * This function marks the specified parameter buffer "unused". + */ +static __inline__ void +release_param(void *p) +{ + atomic_set(&((iucv_param *)p)->in_use, 0); +} + +/** + * iucv_add_handler: - Add a new handler + * @new_handler: handle that is being entered into chain. + * + * Places new handle on iucv_handler_table, if identical handler is not + * found. + * + * Returns: 0 on success, !0 on failure (handler already in chain). + */ +static int +iucv_add_handler (handler *new) +{ + ulong flags; + + iucv_debug(1, "entering"); + iucv_dumpit("handler:", new, sizeof(handler)); + + spin_lock_irqsave (&iucv_lock, flags); + if (!list_empty(&iucv_handler_table)) { + struct list_head *lh; + + /** + * Search list for handler with identical id. If one + * is found, the new handler is _not_ added. + */ + list_for_each(lh, &iucv_handler_table) { + handler *h = list_entry(lh, handler, list); + if (!memcmp(&new->id, &h->id, sizeof(h->id))) { + iucv_debug(1, "ret 1"); + spin_unlock_irqrestore (&iucv_lock, flags); + return 1; + } + } + } + /** + * If we get here, no handler was found. + */ + INIT_LIST_HEAD(&new->list); + list_add(&new->list, &iucv_handler_table); + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_debug(1, "exiting"); + return 0; +} + +/** + * b2f0: + * @code: identifier of IUCV call to CP. + * @parm: pointer to 40 byte iparml area passed to CP + * + * Calls CP to execute IUCV commands. + * + * Returns: return code from CP's IUCV call + */ +static inline ulong b2f0(__u32 code, void *parm) +{ + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); + iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param)); + + reg0 = code; + reg1 = virt_to_phys(parm); + asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1)); + + iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param)); + + return (unsigned long)*((__u8 *)(parm + 3)); +} + +/* + * Name: iucv_add_pathid + * Purpose: Adds a path id to the system. + * Input: pathid - pathid that is going to be entered into system + * handle - address of handler that the pathid will be associated + * with. + * pgm_data - token passed in by application. + * Output: 0: successful addition of pathid + * - EINVAL - pathid entry is being used by another application + * - ENOMEM - storage allocation for a new pathid table failed +*/ +static int +__iucv_add_pathid(__u16 pathid, handler *handler) +{ + + iucv_debug(1, "entering"); + + iucv_debug(1, "handler is pointing to %p", handler); + + if (pathid > (max_connections - 1)) + return -EINVAL; + + if (iucv_pathid_table[pathid]) { + iucv_debug(1, "pathid entry is %p", iucv_pathid_table[pathid]); + printk(KERN_WARNING + "%s: Pathid being used, error.\n", __FUNCTION__); + return -EINVAL; + } + iucv_pathid_table[pathid] = handler; + + iucv_debug(1, "exiting"); + return 0; +} /* end of add_pathid function */ + +static int +iucv_add_pathid(__u16 pathid, handler *handler) +{ + ulong flags; + int rc; + + spin_lock_irqsave (&iucv_lock, flags); + rc = __iucv_add_pathid(pathid, handler); + spin_unlock_irqrestore (&iucv_lock, flags); + return rc; +} + +static void +iucv_remove_pathid(__u16 pathid) +{ + ulong flags; + + if (pathid > (max_connections - 1)) + return; + + spin_lock_irqsave (&iucv_lock, flags); + iucv_pathid_table[pathid] = NULL; + spin_unlock_irqrestore (&iucv_lock, flags); +} + +/** + * iucv_declare_buffer_cpuid + * Register at VM for subsequent IUCV operations. This is executed + * on the reserved CPU iucv_cpuid. Called from iucv_declare_buffer(). + */ +static void +iucv_declare_buffer_cpuid (void *result) +{ + iparml_db *parm; + + parm = (iparml_db *)grab_param(); + parm->ipbfadr1 = virt_to_phys(iucv_external_int_buffer); + if ((*((ulong *)result) = b2f0(DECLARE_BUFFER, parm)) == 1) + *((ulong *)result) = parm->iprcode; + release_param(parm); +} + +/** + * iucv_retrieve_buffer_cpuid: + * Unregister IUCV usage at VM. This is always executed on the same + * cpu that registered the buffer to VM. + * Called from iucv_retrieve_buffer(). + */ +static void +iucv_retrieve_buffer_cpuid (void *cpu) +{ + iparml_control *parm; + + parm = (iparml_control *)grab_param(); + b2f0(RETRIEVE_BUFFER, parm); + release_param(parm); +} + +/** + * Name: iucv_declare_buffer + * Purpose: Specifies the guests real address of an external + * interrupt. + * Input: void + * Output: iprcode - return code from b2f0 call + */ +static int +iucv_declare_buffer (void) +{ + unsigned long flags; + ulong b2f0_result; + + iucv_debug(1, "entering"); + b2f0_result = -ENODEV; + spin_lock_irqsave (&iucv_lock, flags); + if (iucv_cpuid == -1) { + /* Reserve any cpu for use by iucv. */ + iucv_cpuid = smp_get_cpu(CPU_MASK_ALL); + spin_unlock_irqrestore (&iucv_lock, flags); + smp_call_function_on(iucv_declare_buffer_cpuid, + &b2f0_result, 0, 1, iucv_cpuid); + if (b2f0_result) { + smp_put_cpu(iucv_cpuid); + iucv_cpuid = -1; + } + iucv_debug(1, "Address of EIB = %p", iucv_external_int_buffer); + } else { + spin_unlock_irqrestore (&iucv_lock, flags); + b2f0_result = 0; + } + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_retrieve_buffer: + * + * Terminates all use of IUCV. + * Returns: return code from CP + */ +static int +iucv_retrieve_buffer (void) +{ + iucv_debug(1, "entering"); + if (iucv_cpuid != -1) { + smp_call_function_on(iucv_retrieve_buffer_cpuid, + NULL, 0, 1, iucv_cpuid); + /* Release the cpu reserved by iucv_declare_buffer. */ + smp_put_cpu(iucv_cpuid); + iucv_cpuid = -1; + } + iucv_debug(1, "exiting"); + return 0; +} + +/** + * iucv_remove_handler: + * @users_handler: handler to be removed + * + * Remove handler when application unregisters. + */ +static void +iucv_remove_handler(handler *handler) +{ + unsigned long flags; + + if ((!iucv_pathid_table) || (!handler)) + return; + + iucv_debug(1, "entering"); + + spin_lock_irqsave (&iucv_lock, flags); + list_del(&handler->list); + if (list_empty(&iucv_handler_table)) { + if (register_flag) { + unregister_external_interrupt(0x4000, iucv_irq_handler); + register_flag = 0; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_debug(1, "exiting"); + return; +} + +/** + * iucv_register_program: + * @pgmname: user identification + * @userid: machine identification + * @pgmmask: Indicates which bits in the pgmname and userid combined will be + * used to determine who is given control. + * @ops: Address of interrupt handler table. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * Registers an application with IUCV. + * Returns: + * The address of handler, or NULL on failure. + * NOTE on pgmmask: + * If pgmname, userid and pgmmask are provided, pgmmask is entered into the + * handler as is. + * If pgmmask is NULL, the internal mask is set to all 0xff's + * When userid is NULL, the first 8 bytes of the internal mask are forced + * to 0x00. + * If pgmmask and userid are NULL, the first 8 bytes of the internal mask + * are forced to 0x00 and the last 16 bytes to 0xff. + */ + +iucv_handle_t +iucv_register_program (__u8 pgmname[16], + __u8 userid[8], + __u8 pgmmask[24], + iucv_interrupt_ops_t * ops, void *pgm_data) +{ + ulong rc = 0; /* return code from function calls */ + handler *new_handler; + + iucv_debug(1, "entering"); + + if (ops == NULL) { + /* interrupt table is not defined */ + printk(KERN_WARNING "%s: Interrupt table is not defined, " + "exiting\n", __FUNCTION__); + return NULL; + } + if (!pgmname) { + printk(KERN_WARNING "%s: pgmname not provided\n", __FUNCTION__); + return NULL; + } + + /* Allocate handler entry */ + new_handler = kmalloc(sizeof(handler), GFP_ATOMIC); + if (new_handler == NULL) { + printk(KERN_WARNING "%s: storage allocation for new handler " + "failed.\n", __FUNCTION__); + return NULL; + } + + if (!iucv_pathid_table) { + if (iucv_init()) { + kfree(new_handler); + return NULL; + } + + max_connections = iucv_query_maxconn(); + iucv_pathid_table = kcalloc(max_connections, sizeof(handler *), + GFP_ATOMIC); + if (iucv_pathid_table == NULL) { + printk(KERN_WARNING "%s: iucv_pathid_table storage " + "allocation failed\n", __FUNCTION__); + kfree(new_handler); + return NULL; + } + } + memset(new_handler, 0, sizeof (handler)); + memcpy(new_handler->id.user_data, pgmname, + sizeof (new_handler->id.user_data)); + if (userid) { + memcpy (new_handler->id.userid, userid, + sizeof (new_handler->id.userid)); + ASCEBC (new_handler->id.userid, + sizeof (new_handler->id.userid)); + EBC_TOUPPER (new_handler->id.userid, + sizeof (new_handler->id.userid)); + + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); + } else { + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); + } + } else { + if (pgmmask) { + memcpy (new_handler->id.mask, pgmmask, + sizeof (new_handler->id.mask)); + } else { + memset (new_handler->id.mask, 0xFF, + sizeof (new_handler->id.mask)); + } + memset (new_handler->id.userid, 0x00, + sizeof (new_handler->id.userid)); + } + /* fill in the rest of handler */ + new_handler->pgm_data = pgm_data; + new_handler->interrupt_table = ops; + + /* + * Check if someone else is registered with same pgmname, userid + * and mask. If someone is already registered with same pgmname, + * userid and mask, registration will fail and NULL will be returned + * to the application. + * If identical handler not found, then handler is added to list. + */ + rc = iucv_add_handler(new_handler); + if (rc) { + printk(KERN_WARNING "%s: Someone already registered with same " + "pgmname, userid, pgmmask\n", __FUNCTION__); + kfree (new_handler); + return NULL; + } + + rc = iucv_declare_buffer(); + if (rc) { + char *err = "Unknown"; + iucv_remove_handler(new_handler); + kfree(new_handler); + switch(rc) { + case 0x03: + err = "Directory error"; + break; + case 0x0a: + err = "Invalid length"; + break; + case 0x13: + err = "Buffer already exists"; + break; + case 0x3e: + err = "Buffer overlap"; + break; + case 0x5c: + err = "Paging or storage error"; + break; + } + printk(KERN_WARNING "%s: iucv_declare_buffer " + "returned error 0x%02lx (%s)\n", __FUNCTION__, rc, err); + return NULL; + } + if (!register_flag) { + /* request the 0x4000 external interrupt */ + rc = register_external_interrupt (0x4000, iucv_irq_handler); + if (rc) { + iucv_remove_handler(new_handler); + kfree (new_handler); + printk(KERN_WARNING "%s: " + "register_external_interrupt returned %ld\n", + __FUNCTION__, rc); + return NULL; + + } + register_flag = 1; + } + iucv_debug(1, "exiting"); + return new_handler; +} /* end of register function */ + +/** + * iucv_unregister_program: + * @handle: address of handler + * + * Unregister application with IUCV. + * Returns: + * 0 on success, -EINVAL, if specified handle is invalid. + */ + +int +iucv_unregister_program (iucv_handle_t handle) +{ + handler *h = NULL; + struct list_head *lh; + int i; + ulong flags; + + iucv_debug(1, "entering"); + iucv_debug(1, "address of handler is %p", h); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + if (!h) { + spin_unlock_irqrestore (&iucv_lock, flags); + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + /** + * First, walk thru iucv_pathid_table and sever any pathid which is + * still pointing to the handler to be removed. + */ + for (i = 0; i < max_connections; i++) + if (iucv_pathid_table[i] == h) { + spin_unlock_irqrestore (&iucv_lock, flags); + iucv_sever(i, h->id.user_data); + spin_lock_irqsave(&iucv_lock, flags); + } + spin_unlock_irqrestore (&iucv_lock, flags); + + iucv_remove_handler(h); + kfree(h); + + iucv_debug(1, "exiting"); + return 0; +} + +/** + * iucv_accept: + * @pathid: Path identification number + * @msglim_reqstd: The number of outstanding messages requested. + * @user_data: Data specified by the iucv_connect function. + * @flags1: Contains options for this path. + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * @handle: Address of handler. + * @pgm_data: Application data passed to interrupt handlers. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * + * This function is issued after the user receives a Connection Pending external + * interrupt and now wishes to complete the IUCV communication path. + * Returns: + * return code from CP + */ +int +iucv_accept(__u16 pathid, __u16 msglim_reqstd, + __u8 user_data[16], int flags1, + iucv_handle_t handle, void *pgm_data, + int *flags1_out, __u16 * msglim) +{ + ulong b2f0_result = 0; + ulong flags; + struct list_head *lh; + handler *h = NULL; + iparml_control *parm; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + if (!h) { + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + parm = (iparml_control *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsglim = msglim_reqstd; + if (user_data) + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(ACCEPT, parm); + + if (!b2f0_result) { + if (msglim) + *msglim = parm->ipmsglim; + if (pgm_data) + h->pgm_data = pgm_data; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; + } + release_param(parm); + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_connect: + * @pathid: Path identification number + * @msglim_reqstd: Number of outstanding messages requested + * @user_data: 16-byte user data + * @userid: 8-byte of user identification + * @system_name: 8-byte identifying the system name + * @flags1: Specifies options for this path: + * - IPPRTY (0x20) Specifies if you want to send priority message. + * - IPRMDATA (0x80) Specifies whether your program can handle a message + * in the parameter list. + * - IPQUSCE (0x40) Specifies whether you want to quiesce the path being + * established. + * - IPLOCAL (0x01) Allows an application to force the partner to be on the + * local system. If local is specified then target class + * cannot be specified. + * @flags1_out: Pointer to an int. If not NULL, on return the options for + * the path are stored at the given location: + * - IPPRTY (0x20) Indicates you may send a priority message. + * @msglim: Pointer to an __u16. If not NULL, on return the maximum + * number of outstanding messages is stored at the given + * location. + * @handle: Address of handler. + * @pgm_data: Application data to be passed to interrupt handlers. + * + * This function establishes an IUCV path. Although the connect may complete + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Returns: return code from CP, or one of the following + * - ENOMEM + * - return code from iucv_declare_buffer + * - EINVAL - invalid handle passed by application + * - EINVAL - pathid address is NULL + * - ENOMEM - pathid table storage allocation failed + * - return code from internal function add_pathid + */ +int +iucv_connect (__u16 *pathid, __u16 msglim_reqstd, + __u8 user_data[16], __u8 userid[8], + __u8 system_name[8], int flags1, + int *flags1_out, __u16 * msglim, + iucv_handle_t handle, void *pgm_data) +{ + iparml_control *parm; + iparml_control local_parm; + struct list_head *lh; + ulong b2f0_result = 0; + ulong flags; + int add_pathid_result = 0; + handler *h = NULL; + __u8 no_memory[16] = "NO MEMORY"; + + iucv_debug(1, "entering"); + + /* Checking if handle is valid */ + spin_lock_irqsave (&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + if ((handler *)handle == list_entry(lh, handler, list)) { + h = (handler *)handle; + break; + } + } + spin_unlock_irqrestore (&iucv_lock, flags); + + if (!h) { + if (handle) + printk(KERN_WARNING + "%s: Handler not found in iucv_handler_table.\n", + __FUNCTION__); + else + printk(KERN_WARNING + "%s: NULL handle passed by application.\n", + __FUNCTION__); + return -EINVAL; + } + + if (pathid == NULL) { + printk(KERN_WARNING "%s: NULL pathid pointer\n", + __FUNCTION__); + return -EINVAL; + } + + parm = (iparml_control *)grab_param(); + + parm->ipmsglim = msglim_reqstd; + + if (user_data) + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + + if (userid) { + memcpy(parm->ipvmid, userid, sizeof(parm->ipvmid)); + ASCEBC(parm->ipvmid, sizeof(parm->ipvmid)); + EBC_TOUPPER(parm->ipvmid, sizeof(parm->ipvmid)); + } + + if (system_name) { + memcpy(parm->iptarget, system_name, sizeof(parm->iptarget)); + ASCEBC(parm->iptarget, sizeof(parm->iptarget)); + EBC_TOUPPER(parm->iptarget, sizeof(parm->iptarget)); + } + + /* In order to establish an IUCV connection, the procedure is: + * + * b2f0(CONNECT) + * take the ippathid from the b2f0 call + * register the handler to the ippathid + * + * Unfortunately, the ConnectionEstablished message gets sent after the + * b2f0(CONNECT) call but before the register is handled. + * + * In order for this race condition to be eliminated, the IUCV Control + * Interrupts must be disabled for the above procedure. + * + * David Kennedy + */ + + /* Enable everything but IUCV Control messages */ + iucv_setmask(~(AllInterrupts)); + messagesDisabled = 1; + + spin_lock_irqsave (&iucv_lock, flags); + parm->ipflags1 = (__u8)flags1; + b2f0_result = b2f0(CONNECT, parm); + memcpy(&local_parm, parm, sizeof(local_parm)); + release_param(parm); + parm = &local_parm; + if (!b2f0_result) + add_pathid_result = __iucv_add_pathid(parm->ippathid, h); + spin_unlock_irqrestore (&iucv_lock, flags); + + if (b2f0_result) { + iucv_setmask(~0); + messagesDisabled = 0; + return b2f0_result; + } + + *pathid = parm->ippathid; + + /* Enable everything again */ + iucv_setmask(IUCVControlInterruptsFlag); + + if (msglim) + *msglim = parm->ipmsglim; + if (flags1_out) + *flags1_out = (parm->ipflags1 & IPPRTY) ? IPPRTY : 0; + + if (add_pathid_result) { + iucv_sever(*pathid, no_memory); + printk(KERN_WARNING "%s: add_pathid failed with rc =" + " %d\n", __FUNCTION__, add_pathid_result); + return(add_pathid_result); + } + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_purge: + * @pathid: Path identification number + * @msgid: Message ID of message to purge. + * @srccls: Message class of the message to purge. + * @audit: Pointer to an __u32. If not NULL, on return, information about + * asynchronous errors that may have affected the normal completion + * of this message ist stored at the given location. + * + * Cancels a message you have sent. + * Returns: return code from CP + */ +int +iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit) +{ + iparml_purge *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_purge *)grab_param(); + + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->ipsrccls = srccls; + parm->ipflags1 |= (IPSRCCLS | IPFGMID | IPFGPID); + b2f0_result = b2f0(PURGE, parm); + + if (!b2f0_result && audit) { + memcpy(audit, parm->ipaudit, sizeof(parm->ipaudit)); + /* parm->ipaudit has only 3 bytes */ + *audit >>= 8; + } + + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/** + * iucv_query_generic: + * @want_maxconn: Flag, describing which value is to be returned. + * + * Helper function for iucv_query_maxconn() and iucv_query_bufsize(). + * + * Returns: The buffersize, if want_maxconn is 0; the maximum number of + * connections, if want_maxconn is 1 or an error-code < 0 on failure. + */ +static int +iucv_query_generic(int want_maxconn) +{ + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); + iparml_purge *parm = (iparml_purge *)grab_param(); + int bufsize, maxconn; + int ccode; + + /** + * Call b2f0 and store R0 (max buffer size), + * R1 (max connections) and CC. + */ + reg0 = QUERY; + reg1 = virt_to_phys(parm); + asm volatile( + " .long 0xb2f01000\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc"); + bufsize = reg0; + maxconn = reg1; + release_param(parm); + + if (ccode) + return -EPERM; + if (want_maxconn) + return maxconn; + return bufsize; +} + +/** + * iucv_query_maxconn: + * + * Determines the maximum number of connections thay may be established. + * + * Returns: Maximum number of connections that can be. + */ +ulong +iucv_query_maxconn(void) +{ + return iucv_query_generic(1); +} + +/** + * iucv_query_bufsize: + * + * Determines the size of the external interrupt buffer. + * + * Returns: Size of external interrupt buffer. + */ +ulong +iucv_query_bufsize (void) +{ + return iucv_query_generic(0); +} + +/** + * iucv_quiesce: + * @pathid: Path identification number + * @user_data: 16-byte user data + * + * Temporarily suspends incoming messages on an IUCV path. + * You can later reactivate the path by invoking the iucv_resume function. + * Returns: return code from CP + */ +int +iucv_quiesce (__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_control *)grab_param(); + + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; + + b2f0_result = b2f0(QUIESCE, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/** + * iucv_receive: + * @pathid: Path identification number. + * @buffer: Address of buffer to receive. Must be below 2G. + * @buflen: Length of buffer to receive. + * @msgid: Specifies the message ID. + * @trgcls: Specifies target class. + * @flags1_out: Receives options for path on return. + * - IPNORPY (0x10) Specifies whether a reply is required + * - IPPRTY (0x20) Specifies if you want to send priority message + * - IPRMDATA (0x80) Specifies the data is contained in the parameter list + * @residual_buffer: Receives the address of buffer updated by the number + * of bytes you have received on return. + * @residual_length: On return, receives one of the following values: + * - 0 If the receive buffer is the same length as + * the message. + * - Remaining bytes in buffer If the receive buffer is longer than the + * message. + * - Remaining bytes in message If the receive buffer is shorter than the + * message. + * + * This function receives messages that are being sent to you over established + * paths. + * Returns: return code from CP IUCV call; If the receive buffer is shorter + * than the message, always 5 + * -EINVAL - buffer address is pointing to NULL + */ +int +iucv_receive (__u16 pathid, __u32 msgid, __u32 trgcls, + void *buffer, ulong buflen, + int *flags1_out, ulong * residual_buffer, ulong * residual_length) +{ + iparml_db *parm; + ulong b2f0_result; + int moved = 0; /* number of bytes moved from parmlist to buffer */ + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) (addr_t) buffer; + parm->ipbfln1f = (__u32) ((ulong) buflen); + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGPID | IPFGMID | IPFGMCL); + + b2f0_result = b2f0(RECEIVE, parm); + + if (!b2f0_result || b2f0_result == 5) { + if (flags1_out) { + iucv_debug(2, "*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug(2, "*flags1_out = %d", *flags1_out); + } + + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + if (residual_length) + *residual_length = parm->ipbfln1f; + + if (residual_buffer) + *residual_buffer = parm->ipbfadr1; + } else { + moved = min_t (unsigned long, buflen, 8); + + memcpy ((char *) buffer, + (char *) &parm->ipbfadr1, moved); + + if (buflen < 8) + b2f0_result = 5; + + if (residual_length) + *residual_length = abs (buflen - 8); + + if (residual_buffer) + *residual_buffer = (ulong) (buffer + moved); + } + } + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_receive_array + * Purpose: This function receives messages that are being sent to you + * over established paths. + * Input: pathid - path identification number + * buffer - address of array of buffers + * buflen - total length of buffers + * msgid - specifies the message ID. + * trgcls - specifies target class + * Output: + * flags1_out: Options for path. + * IPNORPY - 0x10 specifies whether a reply is required + * IPPRTY - 0x20 specifies if you want to send priority message + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address points to the current list entry IUCV + * is working on. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this case + * b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_receive_array (__u16 pathid, + __u32 msgid, __u32 trgcls, + iucv_array_t * buffer, ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length) +{ + iparml_db *parm; + ulong b2f0_result; + int i = 0, moved = 0, need_to_move = 8, dyn_len; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; + parm->ipmsgid = msgid; + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPBUFLST | IPFGPID | IPFGMID | IPFGMCL); + + b2f0_result = b2f0(RECEIVE, parm); + + if (!b2f0_result || b2f0_result == 5) { + + if (flags1_out) { + iucv_debug(2, "*flags1_out = %d", *flags1_out); + *flags1_out = (parm->ipflags1 & (~0x07)); + iucv_debug(2, "*flags1_out = %d", *flags1_out); + } + + if (!(parm->ipflags1 & IPRMDATA)) { /*msg not in parmlist */ + + if (residual_length) + *residual_length = parm->ipbfln1f; + + if (residual_buffer) + *residual_buffer = parm->ipbfadr1; + + } else { + /* copy msg from parmlist to users array. */ + + while ((moved < 8) && (moved < buflen)) { + dyn_len = + min_t (unsigned int, + (buffer + i)->length, need_to_move); + + memcpy ((char *)((ulong)((buffer + i)->address)), + ((char *) &parm->ipbfadr1) + moved, + dyn_len); + + moved += dyn_len; + need_to_move -= dyn_len; + + (buffer + i)->address = + (__u32) + ((ulong)(__u8 *) ((ulong)(buffer + i)->address) + + dyn_len); + + (buffer + i)->length -= dyn_len; + i++; + } + + if (need_to_move) /* buflen < 8 bytes */ + b2f0_result = 5; + + if (residual_length) + *residual_length = abs (buflen - 8); + + if (residual_buffer) { + if (!moved) + *residual_buffer = (ulong) buffer; + else + *residual_buffer = + (ulong) (buffer + (i - 1)); + } + + } + } + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/** + * iucv_reject: + * @pathid: Path identification number. + * @msgid: Message ID of the message to reject. + * @trgcls: Target class of the message to reject. + * Returns: return code from CP + * + * Refuses a specified message. Between the time you are notified of a + * message and the time that you complete the message, the message may + * be rejected. + */ +int +iucv_reject (__u16 pathid, __u32 msgid, __u32 trgcls) +{ + iparml_db *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPFGMCL | IPFGMID | IPFGPID); + + b2f0_result = b2f0(REJECT, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", b2f0_result); + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- 0x20 - specifies if you want to send priority message + * buffer - address of reply buffer + * buflen - length of reply buffer + * Output: ipbfadr2 - Address of buffer updated by the number + * of bytes you have moved. + * ipbfln2f - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_reply (__u16 pathid, + __u32 msgid, __u32 trgcls, + int flags1, + void *buffer, ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = (__u32) buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (__u8) flags1; /* priority message */ + + b2f0_result = b2f0(REPLY, parm); + + if ((!b2f0_result) || (b2f0_result == 5)) { + if (ipbfadr2) + *ipbfadr2 = parm->ipbfadr2; + if (ipbfln2f) + *ipbfln2f = parm->ipbfln2f; + } + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply_array + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * The array identifies a list of addresses and lengths of + * discontiguous buffers that contains the reply data. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of reply buffers + * buflen - total length of reply buffers + * Output: ipbfadr2 - Address of buffer which IUCV is currently working on. + * ipbfln2f - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL +*/ +int +iucv_reply_array (__u16 pathid, + __u32 msgid, __u32 trgcls, + int flags1, + iucv_array_t * buffer, + ulong buflen, ulong * ipbfadr2, ulong * ipbfln2f) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr2 = (__u32) ((ulong) buffer); + parm->ipbfln2f = buflen; /* length of message */ + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + parm->ipflags1 = (IPANSLST | flags1); + + b2f0_result = b2f0(REPLY, parm); + + if ((!b2f0_result) || (b2f0_result == 5)) { + + if (ipbfadr2) + *ipbfadr2 = parm->ipbfadr2; + if (ipbfln2f) + *ipbfln2f = parm->ipbfln2f; + } + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_reply_prmmsg + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Prmmsg signifies the data is moved into the + * parameter list. + * Input: pathid - path identification number + * msgid - specifies the message ID. + * trgcls - specifies target class + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into the parameter + * list. + * Output: NA + * Return: b2f0_result - return code from CP +*/ +int +iucv_reply_prmmsg (__u16 pathid, + __u32 msgid, __u32 trgcls, int flags1, __u8 prmmsg[8]) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->ipmsgid = msgid; + parm->iptrgcls = trgcls; + memcpy(parm->iprmmsg, prmmsg, sizeof (parm->iprmmsg)); + parm->ipflags1 = (IPRMDATA | flags1); + + b2f0_result = b2f0(REPLY, parm); + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/** + * iucv_resume: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function restores communication over a quiesced path. + * Returns: return code from CP + */ +int +iucv_resume (__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + iucv_debug(1, "pathid = %d", pathid); + + parm = (iparml_control *)grab_param(); + + memcpy (parm->ipuser, user_data, sizeof (*user_data)); + parm->ippathid = pathid; + + b2f0_result = b2f0(RESUME, parm); + release_param(parm); + + iucv_debug(1, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send + * Purpose: sends messages + * Input: pathid - ushort, pathid + * msgid - ulong *, id of message returned to caller + * trgcls - ulong, target message class + * srccls - ulong, source message class + * msgtag - ulong, message tag + * flags1 - Contains options for this path. + * IPPRTY - Ox20 - specifies if you want to send a priority message. + * buffer - pointer to buffer + * buflen - ulong, length of buffer + * Output: b2f0_result - return code from b2f0 call + * msgid - returns message id + */ +int +iucv_send (__u16 pathid, __u32 * msgid, + __u32 trgcls, __u32 srccls, + __u32 msgtag, int flags1, void *buffer, ulong buflen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | flags1); /* one way priority message */ + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated witht the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of send buffers + * buflen - total length of send buffers + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_send_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, int flags1, iucv_array_t * buffer, ulong buflen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPNORPY | IPBUFLST | flags1); + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_send_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into parameter list + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP +*/ +int +iucv_send_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, __u32 msgtag, int flags1, __u8 prmmsg[8]) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPRMDATA | IPNORPY | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer. The receiver + * of the send is expected to reply to the message and + * a buffer is provided into which IUCV moves the reply + * to this message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of send buffer + * buflen - length of send buffer + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer or ansbuf address is NULL + */ +int +iucv_send2way (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + void *buffer, ulong buflen, void *ansbuf, ulong anslen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer || !ansbuf) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = flags1; /* priority message */ + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. The receiver of the send is expected to + * reply to the message and a buffer is provided into which + * IUCV moves the reply to this message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - spcifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * buffer - address of array of send buffers + * buflen - total length of send buffers + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL + */ +int +iucv_send2way_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + iucv_array_t * buffer, + ulong buflen, iucv_array_t * ansbuf, ulong anslen) +{ + iparml_db *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!buffer || !ansbuf) + return -EINVAL; + + parm = (iparml_db *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipbfadr1 = (__u32) ((ulong) buffer); + parm->ipbfln1f = (__u32) buflen; /* length of message */ + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipflags1 = (IPBUFLST | IPANSLST | flags1); + b2f0_result = b2f0(SEND, parm); + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +/* + * Name: iucv_send2way_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed in parameter list + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - buffer address is NULL +*/ +int +iucv_send2way_prmmsg (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + ulong flags1, __u8 prmmsg[8], void *ansbuf, ulong anslen) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!ansbuf) + return -EINVAL; + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | flags1); /* message in prmlist */ + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + + b2f0_result = b2f0(SEND, parm); + + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + + return b2f0_result; +} + +/* + * Name: iucv_send2way_prmmsg_array + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. The contents of ansbuf is the address of the + * array of addresses and lengths of discontiguous buffers + * that contain the reply. + * Input: pathid - path identification number + * trgcls - specifies target class + * srccls - specifies the source message class + * msgtag - specifies a tag to be associated with the message + * flags1 - option for path + * IPPRTY- specifies if you want to send priority message + * prmmsg - 8-bytes of data to be placed into the parameter list + * ansbuf - address of buffer to reply with + * anslen - length of buffer to reply with + * Output: msgid - specifies the message ID. + * Return: b2f0_result - return code from CP + * (-EINVAL) - ansbuf address is NULL + */ +int +iucv_send2way_prmmsg_array (__u16 pathid, + __u32 * msgid, + __u32 trgcls, + __u32 srccls, + __u32 msgtag, + int flags1, + __u8 prmmsg[8], + iucv_array_t * ansbuf, ulong anslen) +{ + iparml_dpl *parm; + ulong b2f0_result; + + iucv_debug(2, "entering"); + + if (!ansbuf) + return -EINVAL; + + parm = (iparml_dpl *)grab_param(); + + parm->ippathid = pathid; + parm->iptrgcls = trgcls; + parm->ipsrccls = srccls; + parm->ipmsgtag = msgtag; + parm->ipbfadr2 = (__u32) ((ulong) ansbuf); + parm->ipbfln2f = (__u32) anslen; + parm->ipflags1 = (IPRMDATA | IPANSLST | flags1); + memcpy(parm->iprmmsg, prmmsg, sizeof(parm->iprmmsg)); + b2f0_result = b2f0(SEND, parm); + if ((!b2f0_result) && (msgid)) + *msgid = parm->ipmsgid; + release_param(parm); + + iucv_debug(2, "exiting"); + return b2f0_result; +} + +void +iucv_setmask_cpuid (void *result) +{ + iparml_set_mask *parm; + + iucv_debug(1, "entering"); + parm = (iparml_set_mask *)grab_param(); + parm->ipmask = *((__u8*)result); + *((ulong *)result) = b2f0(SETMASK, parm); + release_param(parm); + + iucv_debug(1, "b2f0_result = %ld", *((ulong *)result)); + iucv_debug(1, "exiting"); +} + +/* + * Name: iucv_setmask + * Purpose: This function enables or disables the following IUCV + * external interruptions: Nonpriority and priority message + * interrupts, nonpriority and priority reply interrupts. + * Input: SetMaskFlag - options for interrupts + * 0x80 - Nonpriority_MessagePendingInterruptsFlag + * 0x40 - Priority_MessagePendingInterruptsFlag + * 0x20 - Nonpriority_MessageCompletionInterruptsFlag + * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag + * Output: NA + * Return: b2f0_result - return code from CP +*/ +int +iucv_setmask (int SetMaskFlag) +{ + union { + ulong result; + __u8 param; + } u; + int cpu; + + u.param = SetMaskFlag; + cpu = get_cpu(); + smp_call_function_on(iucv_setmask_cpuid, &u, 0, 1, iucv_cpuid); + put_cpu(); + + return u.result; +} + +/** + * iucv_sever: + * @pathid: Path identification number + * @user_data: 16-byte of user data + * + * This function terminates an iucv path. + * Returns: return code from CP + */ +int +iucv_sever(__u16 pathid, __u8 user_data[16]) +{ + iparml_control *parm; + ulong b2f0_result = 0; + + iucv_debug(1, "entering"); + parm = (iparml_control *)grab_param(); + + memcpy(parm->ipuser, user_data, sizeof(parm->ipuser)); + parm->ippathid = pathid; + + b2f0_result = b2f0(SEVER, parm); + + if (!b2f0_result) + iucv_remove_pathid(pathid); + release_param(parm); + + iucv_debug(1, "exiting"); + return b2f0_result; +} + +/* + * Interrupt Handlers + *******************************************************************************/ + +/** + * iucv_irq_handler: + * @regs: Current registers + * @code: irq code + * + * Handles external interrupts coming in from CP. + * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler(). + */ +static void +iucv_irq_handler(__u16 code) +{ + iucv_irqdata *irqdata; + + irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC); + if (!irqdata) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + return; + } + + memcpy(&irqdata->data, iucv_external_int_buffer, + sizeof(iucv_GeneralInterrupt)); + + spin_lock(&iucv_irq_queue_lock); + list_add_tail(&irqdata->queue, &iucv_irq_queue); + spin_unlock(&iucv_irq_queue_lock); + + tasklet_schedule(&iucv_tasklet); +} + +/** + * iucv_do_int: + * @int_buf: Pointer to copy of external interrupt buffer + * + * The workhorse for handling interrupts queued by iucv_irq_handler(). + * This function is called from the bottom half iucv_tasklet_handler(). + */ +static void +iucv_do_int(iucv_GeneralInterrupt * int_buf) +{ + handler *h = NULL; + struct list_head *lh; + ulong flags; + iucv_interrupt_ops_t *interrupt = NULL; /* interrupt addresses */ + __u8 temp_buff1[24], temp_buff2[24]; /* masked handler id. */ + int rc = 0, j = 0; + __u8 no_listener[16] = "NO LISTENER"; + + iucv_debug(2, "entering, pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); + iucv_dumpit("External Interrupt Buffer:", + int_buf, sizeof(iucv_GeneralInterrupt)); + + ASCEBC (no_listener, 16); + + if (int_buf->iptype != 01) { + if ((int_buf->ippathid) > (max_connections - 1)) { + printk(KERN_WARNING "%s: Got interrupt with pathid %d" + " > max_connections (%ld)\n", __FUNCTION__, + int_buf->ippathid, max_connections - 1); + } else { + h = iucv_pathid_table[int_buf->ippathid]; + interrupt = h->interrupt_table; + iucv_dumpit("Handler:", h, sizeof(handler)); + } + } + + /* end of if statement */ + switch (int_buf->iptype) { + case 0x01: /* connection pending */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + spin_lock_irqsave(&iucv_lock, flags); + list_for_each(lh, &iucv_handler_table) { + h = list_entry(lh, handler, list); + memcpy(temp_buff1, &(int_buf->ipvmid), 24); + memcpy(temp_buff2, &(h->id.userid), 24); + for (j = 0; j < 24; j++) { + temp_buff1[j] &= (h->id.mask)[j]; + temp_buff2[j] &= (h->id.mask)[j]; + } + + iucv_dumpit("temp_buff1:", + temp_buff1, sizeof(temp_buff1)); + iucv_dumpit("temp_buff2", + temp_buff2, sizeof(temp_buff2)); + + if (!memcmp (temp_buff1, temp_buff2, 24)) { + + iucv_debug(2, + "found a matching handler"); + break; + } else + h = NULL; + } + spin_unlock_irqrestore (&iucv_lock, flags); + if (h) { + /* ADD PATH TO PATHID TABLE */ + rc = iucv_add_pathid(int_buf->ippathid, h); + if (rc) { + iucv_sever (int_buf->ippathid, + no_listener); + iucv_debug(1, + "add_pathid failed, rc = %d", + rc); + } else { + interrupt = h->interrupt_table; + if (interrupt->ConnectionPending) { + EBCASC (int_buf->ipvmid, 8); + interrupt->ConnectionPending( + (iucv_ConnectionPending *)int_buf, + h->pgm_data); + } else + iucv_sever(int_buf->ippathid, + no_listener); + } + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x02: /*connection complete */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionComplete) + { + interrupt->ConnectionComplete( + (iucv_ConnectionComplete *)int_buf, + h->pgm_data); + } + else + iucv_debug(1, + "ConnectionComplete not called"); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x03: /* connection severed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionSevered) + interrupt->ConnectionSevered( + (iucv_ConnectionSevered *)int_buf, + h->pgm_data); + + else + iucv_sever (int_buf->ippathid, no_listener); + } else + iucv_sever(int_buf->ippathid, no_listener); + break; + + case 0x04: /* connection quiesced */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionQuiesced) + interrupt->ConnectionQuiesced( + (iucv_ConnectionQuiesced *)int_buf, + h->pgm_data); + else + iucv_debug(1, + "ConnectionQuiesced not called"); + } + break; + + case 0x05: /* connection resumed */ + if (messagesDisabled) { + iucv_setmask(~0); + messagesDisabled = 0; + } + if (h) { + if (interrupt->ConnectionResumed) + interrupt->ConnectionResumed( + (iucv_ConnectionResumed *)int_buf, + h->pgm_data); + else + iucv_debug(1, + "ConnectionResumed not called"); + } + break; + + case 0x06: /* priority message complete */ + case 0x07: /* nonpriority message complete */ + if (h) { + if (interrupt->MessageComplete) + interrupt->MessageComplete( + (iucv_MessageComplete *)int_buf, + h->pgm_data); + else + iucv_debug(2, + "MessageComplete not called"); + } + break; + + case 0x08: /* priority message pending */ + case 0x09: /* nonpriority message pending */ + if (h) { + if (interrupt->MessagePending) + interrupt->MessagePending( + (iucv_MessagePending *) int_buf, + h->pgm_data); + else + iucv_debug(2, + "MessagePending not called"); + } + break; + default: /* unknown iucv type */ + printk(KERN_WARNING "%s: unknown iucv interrupt\n", + __FUNCTION__); + break; + } /* end switch */ + + iucv_debug(2, "exiting pathid %d, type %02X", + int_buf->ippathid, int_buf->iptype); + + return; +} + +/** + * iucv_tasklet_handler: + * + * This function loops over the queue of irq buffers and runs iucv_do_int() + * on every queue element. + */ +static void +iucv_tasklet_handler(unsigned long ignored) +{ + struct list_head head; + struct list_head *next; + ulong flags; + + spin_lock_irqsave(&iucv_irq_queue_lock, flags); + list_add(&head, &iucv_irq_queue); + list_del_init(&iucv_irq_queue); + spin_unlock_irqrestore (&iucv_irq_queue_lock, flags); + + next = head.next; + while (next != &head) { + iucv_irqdata *p = list_entry(next, iucv_irqdata, queue); + + next = next->next; + iucv_do_int(&p->data); + kfree(p); + } + + return; +} + +subsys_initcall(iucv_init); +module_exit(iucv_exit); + +/** + * Export all public stuff + */ +EXPORT_SYMBOL (iucv_bus); +EXPORT_SYMBOL (iucv_root); +EXPORT_SYMBOL (iucv_accept); +EXPORT_SYMBOL (iucv_connect); +#if 0 +EXPORT_SYMBOL (iucv_purge); +EXPORT_SYMBOL (iucv_query_maxconn); +EXPORT_SYMBOL (iucv_query_bufsize); +EXPORT_SYMBOL (iucv_quiesce); +#endif +EXPORT_SYMBOL (iucv_receive); +#if 0 +EXPORT_SYMBOL (iucv_receive_array); +#endif +EXPORT_SYMBOL (iucv_reject); +#if 0 +EXPORT_SYMBOL (iucv_reply); +EXPORT_SYMBOL (iucv_reply_array); +EXPORT_SYMBOL (iucv_resume); +#endif +EXPORT_SYMBOL (iucv_reply_prmmsg); +EXPORT_SYMBOL (iucv_send); +EXPORT_SYMBOL (iucv_send2way); +EXPORT_SYMBOL (iucv_send2way_array); +EXPORT_SYMBOL (iucv_send2way_prmmsg); +EXPORT_SYMBOL (iucv_send2way_prmmsg_array); +#if 0 +EXPORT_SYMBOL (iucv_send_array); +EXPORT_SYMBOL (iucv_send_prmmsg); +EXPORT_SYMBOL (iucv_setmask); +#endif +EXPORT_SYMBOL (iucv_sever); +EXPORT_SYMBOL (iucv_register_program); +EXPORT_SYMBOL (iucv_unregister_program); diff --git a/trunk/drivers/s390/net/iucv.h b/trunk/drivers/s390/net/iucv.h new file mode 100644 index 000000000000..5b6b1b7241c9 --- /dev/null +++ b/trunk/drivers/s390/net/iucv.h @@ -0,0 +1,849 @@ +/* + * drivers/s390/net/iucv.h + * IUCV base support. + * + * S390 version + * Copyright (C) 2000 IBM Corporation + * Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) + * Xenia Tkatschow (xenia@us.ibm.com) + * + * + * Functionality: + * To explore any of the IUCV functions, one must first register + * their program using iucv_register_program(). Once your program has + * successfully completed a register, it can exploit the other functions. + * For furthur reference on all IUCV functionality, refer to the + * CP Programming Services book, also available on the web + * thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 + * + * Definition of Return Codes + * -All positive return codes including zero are reflected back + * from CP except for iucv_register_program. The definition of each + * return code can be found in CP Programming Services book. + * Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760 + * - Return Code of: + * (-EINVAL) Invalid value + * (-ENOMEM) storage allocation failed + * pgmask defined in iucv_register_program will be set depending on input + * paramters. + * + */ + +#include +#include + +/** + * Debug Facility stuff + */ +#define IUCV_DBF_SETUP_NAME "iucv_setup" +#define IUCV_DBF_SETUP_LEN 32 +#define IUCV_DBF_SETUP_PAGES 2 +#define IUCV_DBF_SETUP_NR_AREAS 1 +#define IUCV_DBF_SETUP_LEVEL 3 + +#define IUCV_DBF_DATA_NAME "iucv_data" +#define IUCV_DBF_DATA_LEN 128 +#define IUCV_DBF_DATA_PAGES 2 +#define IUCV_DBF_DATA_NR_AREAS 1 +#define IUCV_DBF_DATA_LEVEL 2 + +#define IUCV_DBF_TRACE_NAME "iucv_trace" +#define IUCV_DBF_TRACE_LEN 16 +#define IUCV_DBF_TRACE_PAGES 4 +#define IUCV_DBF_TRACE_NR_AREAS 1 +#define IUCV_DBF_TRACE_LEVEL 3 + +#define IUCV_DBF_TEXT(name,level,text) \ + do { \ + debug_text_event(iucv_dbf_##name,level,text); \ + } while (0) + +#define IUCV_DBF_HEX(name,level,addr,len) \ + do { \ + debug_event(iucv_dbf_##name,level,(void*)(addr),len); \ + } while (0) + +DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); + +#define IUCV_DBF_TEXT_(name,level,text...) \ + do { \ + char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \ + sprintf(iucv_dbf_txt_buf, text); \ + debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \ + put_cpu_var(iucv_dbf_txt_buf); \ + } while (0) + +#define IUCV_DBF_SPRINTF(name,level,text...) \ + do { \ + debug_sprintf_event(iucv_dbf_trace, level, ##text ); \ + debug_sprintf_event(iucv_dbf_trace, level, text ); \ + } while (0) + +/** + * some more debug stuff + */ +#define IUCV_HEXDUMP16(importance,header,ptr) \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ + *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ + *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ + *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ + *(((char*)ptr)+12),*(((char*)ptr)+13), \ + *(((char*)ptr)+14),*(((char*)ptr)+15)); \ +PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ + "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ + *(((char*)ptr)+16),*(((char*)ptr)+17), \ + *(((char*)ptr)+18),*(((char*)ptr)+19), \ + *(((char*)ptr)+20),*(((char*)ptr)+21), \ + *(((char*)ptr)+22),*(((char*)ptr)+23), \ + *(((char*)ptr)+24),*(((char*)ptr)+25), \ + *(((char*)ptr)+26),*(((char*)ptr)+27), \ + *(((char*)ptr)+28),*(((char*)ptr)+29), \ + *(((char*)ptr)+30),*(((char*)ptr)+31)); + +static inline void +iucv_hex_dump(unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (i && !(i % 16)) + printk("\n"); + printk("%02x ", *(buf + i)); + } + printk("\n"); +} +/** + * end of debug stuff + */ + +#define uchar unsigned char +#define ushort unsigned short +#define ulong unsigned long +#define iucv_handle_t void * + +/* flags1: + * All flags are defined in the field IPFLAGS1 of each function + * and can be found in CP Programming Services. + * IPLOCAL - Indicates the connect can only be satisfied on the + * local system + * IPPRTY - Indicates a priority message + * IPQUSCE - Indicates you do not want to receive messages on a + * path until an iucv_resume is issued + * IPRMDATA - Indicates that the message is in the parameter list + */ +#define IPLOCAL 0x01 +#define IPPRTY 0x20 +#define IPQUSCE 0x40 +#define IPRMDATA 0x80 + +/* flags1_out: + * All flags are defined in the output field of IPFLAGS1 for each function + * and can be found in CP Programming Services. + * IPNORPY - Specifies this is a one-way message and no reply is expected. + * IPPRTY - Indicates a priority message is permitted. Defined in flags1. + */ +#define IPNORPY 0x10 + +#define Nonpriority_MessagePendingInterruptsFlag 0x80 +#define Priority_MessagePendingInterruptsFlag 0x40 +#define Nonpriority_MessageCompletionInterruptsFlag 0x20 +#define Priority_MessageCompletionInterruptsFlag 0x10 +#define IUCVControlInterruptsFlag 0x08 +#define AllInterrupts 0xf8 +/* + * Mapping of external interrupt buffers should be used with the corresponding + * interrupt types. + * Names: iucv_ConnectionPending -> connection pending + * iucv_ConnectionComplete -> connection complete + * iucv_ConnectionSevered -> connection severed + * iucv_ConnectionQuiesced -> connection quiesced + * iucv_ConnectionResumed -> connection resumed + * iucv_MessagePending -> message pending + * iucv_MessageComplete -> message complete + */ +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u16 ipmsglim; + u16 res1; + uchar ipvmid[8]; + uchar ipuser[16]; + u32 res3; + uchar ippollfg; + uchar res4[3]; +} iucv_ConnectionPending; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u16 ipmsglim; + u16 res1; + uchar res2[8]; + uchar ipuser[16]; + u32 res3; + uchar ippollfg; + uchar res4[3]; +} iucv_ConnectionComplete; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionSevered; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionQuiesced; + +typedef struct { + u16 ippathid; + uchar res1; + uchar iptype; + u32 res2; + uchar res3[8]; + uchar ipuser[16]; + u32 res4; + uchar ippollfg; + uchar res5[3]; +} iucv_ConnectionResumed; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u32 ipmsgid; + u32 iptrgcls; + union u2 { + u32 iprmmsg1_u32; + uchar iprmmsg1[4]; + } ln1msg1; + union u1 { + u32 ipbfln1f; + uchar iprmmsg2[4]; + } ln1msg2; + u32 res1[3]; + u32 ipbfln2f; + uchar ippollfg; + uchar res2[3]; +} iucv_MessagePending; + +typedef struct { + u16 ippathid; + uchar ipflags1; + uchar iptype; + u32 ipmsgid; + u32 ipaudit; + uchar iprmmsg[8]; + u32 ipsrccls; + u32 ipmsgtag; + u32 res; + u32 ipbfln2f; + uchar ippollfg; + uchar res2[3]; +} iucv_MessageComplete; + +/* + * iucv_interrupt_ops_t: Is a vector of functions that handle + * IUCV interrupts. + * Parameter list: + * eib - is a pointer to a 40-byte area described + * with one of the structures above. + * pgm_data - this data is strictly for the + * interrupt handler that is passed by + * the application. This may be an address + * or token. +*/ +typedef struct { + void (*ConnectionPending) (iucv_ConnectionPending * eib, + void *pgm_data); + void (*ConnectionComplete) (iucv_ConnectionComplete * eib, + void *pgm_data); + void (*ConnectionSevered) (iucv_ConnectionSevered * eib, + void *pgm_data); + void (*ConnectionQuiesced) (iucv_ConnectionQuiesced * eib, + void *pgm_data); + void (*ConnectionResumed) (iucv_ConnectionResumed * eib, + void *pgm_data); + void (*MessagePending) (iucv_MessagePending * eib, void *pgm_data); + void (*MessageComplete) (iucv_MessageComplete * eib, void *pgm_data); +} iucv_interrupt_ops_t; + +/* + *iucv_array_t : Defines buffer array. + * Inside the array may be 31- bit addresses and 31-bit lengths. +*/ +typedef struct { + u32 address; + u32 length; +} iucv_array_t __attribute__ ((aligned (8))); + +extern struct bus_type iucv_bus; +extern struct device *iucv_root; + +/* -prototypes- */ +/* + * Name: iucv_register_program + * Purpose: Registers an application with IUCV + * Input: prmname - user identification + * userid - machine identification + * pgmmask - indicates which bits in the prmname and userid combined will be + * used to determine who is given control + * ops - address of vector of interrupt handlers + * pgm_data- application data passed to interrupt handlers + * Output: NA + * Return: address of handler + * (0) - Error occurred, registration not completed. + * NOTE: Exact cause of failure will be recorded in syslog. +*/ +iucv_handle_t iucv_register_program (uchar pgmname[16], + uchar userid[8], + uchar pgmmask[24], + iucv_interrupt_ops_t * ops, + void *pgm_data); + +/* + * Name: iucv_unregister_program + * Purpose: Unregister application with IUCV + * Input: address of handler + * Output: NA + * Return: (0) - Normal return + * (-EINVAL) - Internal error, wild pointer +*/ +int iucv_unregister_program (iucv_handle_t handle); + +/* + * Name: iucv_accept + * Purpose: This function is issued after the user receives a Connection Pending external + * interrupt and now wishes to complete the IUCV communication path. + * Input: pathid - u16 , Path identification number + * msglim_reqstd - u16, The number of outstanding messages requested. + * user_data - uchar[16], Data specified by the iucv_connect function. + * flags1 - int, Contains options for this path. + * -IPPRTY - 0x20- Specifies if you want to send priority message. + * -IPRMDATA - 0x80, Specifies whether your program can handle a message + * in the parameter list. + * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being + * established. + * handle - iucv_handle_t, Address of handler. + * pgm_data - void *, Application data passed to interrupt handlers. + * flags1_out - int * Contains information about the path + * - IPPRTY - 0x20, Indicates you may send priority messages. + * msglim - *u16, Number of outstanding messages. + * Output: return code from CP IUCV call. +*/ + +int iucv_accept (u16 pathid, + u16 msglim_reqstd, + uchar user_data[16], + int flags1, + iucv_handle_t handle, + void *pgm_data, int *flags1_out, u16 * msglim); + +/* + * Name: iucv_connect + * Purpose: This function establishes an IUCV path. Although the connect may complete + * successfully, you are not able to use the path until you receive an IUCV + * Connection Complete external interrupt. + * Input: pathid - u16 *, Path identification number + * msglim_reqstd - u16, Number of outstanding messages requested + * user_data - uchar[16], 16-byte user data + * userid - uchar[8], User identification + * system_name - uchar[8], 8-byte identifying the system name + * flags1 - int, Contains options for this path. + * -IPPRTY - 0x20, Specifies if you want to send priority message. + * -IPRMDATA - 0x80, Specifies whether your program can handle a message + * in the parameter list. + * -IPQUSCE - 0x40, Specifies whether you want to quiesce the path being + * established. + * -IPLOCAL - 0X01, Allows an application to force the partner to be on + * the local system. If local is specified then target class cannot be + * specified. + * flags1_out - int * Contains information about the path + * - IPPRTY - 0x20, Indicates you may send priority messages. + * msglim - * u16, Number of outstanding messages + * handle - iucv_handle_t, Address of handler + * pgm_data - void *, Application data passed to interrupt handlers + * Output: return code from CP IUCV call + * rc - return code from iucv_declare_buffer + * -EINVAL - Invalid handle passed by application + * -EINVAL - Pathid address is NULL + * add_pathid_result - Return code from internal function add_pathid +*/ +int + iucv_connect (u16 * pathid, + u16 msglim_reqstd, + uchar user_data[16], + uchar userid[8], + uchar system_name[8], + int flags1, + int *flags1_out, + u16 * msglim, iucv_handle_t handle, void *pgm_data); + +/* + * Name: iucv_purge + * Purpose: This function cancels a message that you have sent. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID of the message to be purged. + * srccls - Specifies the source message class. + * Output: audit - Contains information about asynchronous error + * that may have affected the normal completion + * of this message. + * Return: Return code from CP IUCV call. +*/ +int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit); +/* + * Name: iucv_query_maxconn + * Purpose: This function determines the maximum number of communication paths you + * may establish. + * Return: maxconn - ulong, Maximum number of connection the virtual machine may + * establish. +*/ +ulong iucv_query_maxconn (void); + +/* + * Name: iucv_query_bufsize + * Purpose: This function determines how large an external interrupt + * buffer IUCV requires to store information. + * Return: bufsize - ulong, Size of external interrupt buffer. + */ +ulong iucv_query_bufsize (void); + +/* + * Name: iucv_quiesce + * Purpose: This function temporarily suspends incoming messages on an + * IUCV path. You can later reactivate the path by invoking + * the iucv_resume function. + * Input: pathid - Path identification number + * user_data - 16-bytes of user data + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_quiesce (u16 pathid, uchar user_data[16]); + +/* + * Name: iucv_receive + * Purpose: This function receives messages that are being sent to you + * over established paths. Data will be returned in buffer for length of + * buflen. + * Input: + * pathid - Path identification number. + * buffer - Address of buffer to receive. + * buflen - Length of buffer to receive. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: + * flags1_out: int *, Contains information about this path. + * IPNORPY - 0x10 Specifies this is a one-way message and no reply is + * expected. + * IPPRTY - 0x20 Specifies if you want to send priority message. + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address of buffer updated by the number + * of bytes you have received. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - buffer address is pointing to NULL +*/ +int iucv_receive (u16 pathid, + u32 msgid, + u32 trgcls, + void *buffer, + ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length); + + /* + * Name: iucv_receive_array + * Purpose: This function receives messages that are being sent to you + * over established paths. Data will be returned in first buffer for + * length of first buffer. + * Input: pathid - Path identification number. + * msgid - specifies the message ID. + * trgcls - Specifies target class. + * buffer - Address of array of buffers. + * buflen - Total length of buffers. + * Output: + * flags1_out: int *, Contains information about this path. + * IPNORPY - 0x10 Specifies this is a one-way message and no reply is + * expected. + * IPPRTY - 0x20 Specifies if you want to send priority message. + * IPRMDATA - 0x80 specifies the data is contained in the parameter list + * residual_buffer - address points to the current list entry IUCV + * is working on. + * residual_length - + * Contains one of the following values, if the receive buffer is: + * The same length as the message, this field is zero. + * Longer than the message, this field contains the number of + * bytes remaining in the buffer. + * Shorter than the message, this field contains the residual + * count (that is, the number of bytes remaining in the + * message that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. + */ +int iucv_receive_array (u16 pathid, + u32 msgid, + u32 trgcls, + iucv_array_t * buffer, + ulong buflen, + int *flags1_out, + ulong * residual_buffer, ulong * residual_length); + +/* + * Name: iucv_reject + * Purpose: The reject function refuses a specified message. Between the + * time you are notified of a message and the time that you + * complete the message, the message may be rejected. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_reject (u16 pathid, u32 msgid, u32 trgcls); + +/* + * Name: iucv_reply + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20, Specifies if you want to send priority message. + * buffer - Address of reply buffer. + * buflen - Length of reply buffer. + * Output: residual_buffer - Address of buffer updated by the number + * of bytes you have moved. + * residual_length - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_reply (u16 pathid, + u32 msgid, + u32 trgcls, + int flags1, + void *buffer, ulong buflen, ulong * residual_buffer, + ulong * residual_length); + +/* + * Name: iucv_reply_array + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * The array identifies a list of addresses and lengths of + * discontiguous buffers that contains the reply data. + * Input: pathid - Path identification number + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20, Specifies if you want to send priority message. + * buffer - Address of array of reply buffers. + * buflen - Total length of reply buffers. + * Output: residual_buffer - Address of buffer which IUCV is currently working on. + * residual_length - Contains one of the following values: + * If the answer buffer is the same length as the reply, this field + * contains zero. + * If the answer buffer is longer than the reply, this field contains + * the number of bytes remaining in the buffer. + * If the answer buffer is shorter than the reply, this field contains + * a residual count (that is, the number of bytes remianing in the + * reply that does not fit into the buffer. In this + * case b2f0_result = 5. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_reply_array (u16 pathid, + u32 msgid, + u32 trgcls, + int flags1, + iucv_array_t * buffer, + ulong buflen, ulong * residual_address, + ulong * residual_length); + +/* + * Name: iucv_reply_prmmsg + * Purpose: This function responds to the two-way messages that you + * receive. You must identify completely the message to + * which you wish to reply. ie, pathid, msgid, and trgcls. + * Prmmsg signifies the data is moved into the + * parameter list. + * Input: pathid - Path identification number. + * msgid - Specifies the message ID. + * trgcls - Specifies target class. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into the parameter. + * list. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_reply_prmmsg (u16 pathid, + u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]); + +/* + * Name: iucv_resume + * Purpose: This function restores communications over a quiesced path + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_resume (u16 pathid, uchar user_data[16]); + +/* + * Name: iucv_send + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer and this is a + * one-way message and the receiver will not reply to the + * message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen); + +/* + * Name: iucv_send_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated witht the message. + * flags1 - Option for path. + * IPPRTY- specifies if you want to send priority message. + * buffer - Address of array of send buffers. + * buflen - Total length of send buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, iucv_array_t * buffer, ulong buflen); + +/* + * Name: iucv_send_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a one-way message and the + * receiver will not reply to the message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into parameter list. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. +*/ +int iucv_send_prmmsg (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]); + +/* + * Name: iucv_send2way + * Purpose: This function transmits data to another application. + * Data to be transmitted is in a buffer. The receiver + * of the send is expected to reply to the message and + * a buffer is provided into which IUCV moves the reply + * to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Address of send buffer. + * buflen - Length of send buffer. + * ansbuf - Address of buffer into which IUCV moves the reply of + * this message. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer or ansbuf address is NULL. +*/ +int iucv_send2way (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + void *buffer, ulong buflen, void *ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_array + * Purpose: This function transmits data to another application. + * The contents of buffer is the address of the array of + * addresses and lengths of discontiguous buffers that hold + * the message text. The receiver of the send is expected to + * reply to the message and a buffer is provided into which + * IUCV moves the reply to this message. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * buffer - Sddress of array of send buffers. + * buflen - Total length of send buffers. + * ansbuf - Address of array of buffer into which IUCV moves the reply + * of this message. + * anslen - Address of length reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send2way_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + iucv_array_t * buffer, + ulong buflen, iucv_array_t * ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_prmmsg + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. + * Input: pathid - Rath identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 Specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed in parameter list. + * ansbuf - Address of buffer into which IUCV moves the reply of + * this message. + * anslen - Address of length of buffer. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Buffer address is NULL. +*/ +int iucv_send2way_prmmsg (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + ulong flags1, + uchar prmmsg[8], void *ansbuf, ulong anslen); + +/* + * Name: iucv_send2way_prmmsg_array + * Purpose: This function transmits data to another application. + * Prmmsg specifies that the 8-bytes of data are to be moved + * into the parameter list. This is a two-way message and the + * receiver of the message is expected to reply. A buffer + * is provided into which IUCV moves the reply to this + * message. The contents of ansbuf is the address of the + * array of addresses and lengths of discontiguous buffers + * that contain the reply. + * Input: pathid - Path identification number. + * trgcls - Specifies target class. + * srccls - Specifies the source message class. + * msgtag - Specifies a tag to be associated with the message. + * flags1 - Option for path. + * IPPRTY- 0x20 specifies if you want to send priority message. + * prmmsg - 8-bytes of data to be placed into the parameter list. + * ansbuf - Address of array of buffer into which IUCV moves the reply + * of this message. + * anslen - Address of length of reply buffers. + * Output: msgid - Specifies the message ID. + * Return: Return code from CP IUCV call. + * (-EINVAL) - Ansbuf address is NULL. +*/ +int iucv_send2way_prmmsg_array (u16 pathid, + u32 * msgid, + u32 trgcls, + u32 srccls, + u32 msgtag, + int flags1, + uchar prmmsg[8], + iucv_array_t * ansbuf, ulong anslen); + +/* + * Name: iucv_setmask + * Purpose: This function enables or disables the following IUCV + * external interruptions: Nonpriority and priority message + * interrupts, nonpriority and priority reply interrupts. + * Input: SetMaskFlag - options for interrupts + * 0x80 - Nonpriority_MessagePendingInterruptsFlag + * 0x40 - Priority_MessagePendingInterruptsFlag + * 0x20 - Nonpriority_MessageCompletionInterruptsFlag + * 0x10 - Priority_MessageCompletionInterruptsFlag + * 0x08 - IUCVControlInterruptsFlag + * Output: NA + * Return: Return code from CP IUCV call. +*/ +int iucv_setmask (int SetMaskFlag); + +/* + * Name: iucv_sever + * Purpose: This function terminates an IUCV path. + * Input: pathid - Path identification number. + * user_data - 16-bytes of user data. + * Output: NA + * Return: Return code from CP IUCV call. + * (-EINVAL) - Interal error, wild pointer. +*/ +int iucv_sever (u16 pathid, uchar user_data[16]); diff --git a/trunk/drivers/s390/net/netiucv.c b/trunk/drivers/s390/net/netiucv.c index 6387b483f2bf..3346088f47e0 100644 --- a/trunk/drivers/s390/net/netiucv.c +++ b/trunk/drivers/s390/net/netiucv.c @@ -1,7 +1,7 @@ /* * IUCV network driver * - * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) * * Sysfs integration and all bugs therein by Cornelia Huck @@ -58,94 +58,13 @@ #include #include -#include +#include "iucv.h" #include "fsm.h" MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); -/** - * Debug Facility stuff - */ -#define IUCV_DBF_SETUP_NAME "iucv_setup" -#define IUCV_DBF_SETUP_LEN 32 -#define IUCV_DBF_SETUP_PAGES 2 -#define IUCV_DBF_SETUP_NR_AREAS 1 -#define IUCV_DBF_SETUP_LEVEL 3 - -#define IUCV_DBF_DATA_NAME "iucv_data" -#define IUCV_DBF_DATA_LEN 128 -#define IUCV_DBF_DATA_PAGES 2 -#define IUCV_DBF_DATA_NR_AREAS 1 -#define IUCV_DBF_DATA_LEVEL 2 - -#define IUCV_DBF_TRACE_NAME "iucv_trace" -#define IUCV_DBF_TRACE_LEN 16 -#define IUCV_DBF_TRACE_PAGES 4 -#define IUCV_DBF_TRACE_NR_AREAS 1 -#define IUCV_DBF_TRACE_LEVEL 3 - -#define IUCV_DBF_TEXT(name,level,text) \ - do { \ - debug_text_event(iucv_dbf_##name,level,text); \ - } while (0) - -#define IUCV_DBF_HEX(name,level,addr,len) \ - do { \ - debug_event(iucv_dbf_##name,level,(void*)(addr),len); \ - } while (0) - -DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); - -#define IUCV_DBF_TEXT_(name,level,text...) \ - do { \ - char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \ - sprintf(iucv_dbf_txt_buf, text); \ - debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \ - put_cpu_var(iucv_dbf_txt_buf); \ - } while (0) - -#define IUCV_DBF_SPRINTF(name,level,text...) \ - do { \ - debug_sprintf_event(iucv_dbf_trace, level, ##text ); \ - debug_sprintf_event(iucv_dbf_trace, level, text ); \ - } while (0) - -/** - * some more debug stuff - */ -#define IUCV_HEXDUMP16(importance,header,ptr) \ -PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ - *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ - *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ - *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ - *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ - *(((char*)ptr)+12),*(((char*)ptr)+13), \ - *(((char*)ptr)+14),*(((char*)ptr)+15)); \ -PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ - "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ - *(((char*)ptr)+16),*(((char*)ptr)+17), \ - *(((char*)ptr)+18),*(((char*)ptr)+19), \ - *(((char*)ptr)+20),*(((char*)ptr)+21), \ - *(((char*)ptr)+22),*(((char*)ptr)+23), \ - *(((char*)ptr)+24),*(((char*)ptr)+25), \ - *(((char*)ptr)+26),*(((char*)ptr)+27), \ - *(((char*)ptr)+28),*(((char*)ptr)+29), \ - *(((char*)ptr)+30),*(((char*)ptr)+31)); - -static inline void iucv_hex_dump(unsigned char *buf, size_t len) -{ - size_t i; - - for (i = 0; i < len; i++) { - if (i && !(i % 16)) - printk("\n"); - printk("%02x ", *(buf + i)); - } - printk("\n"); -} #define PRINTK_HEADER " iucv: " /* for debugging */ @@ -154,25 +73,6 @@ static struct device_driver netiucv_driver = { .bus = &iucv_bus, }; -static int netiucv_callback_connreq(struct iucv_path *, - u8 ipvmid[8], u8 ipuser[16]); -static void netiucv_callback_connack(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connsusp(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_connres(struct iucv_path *, u8 ipuser[16]); -static void netiucv_callback_rx(struct iucv_path *, struct iucv_message *); -static void netiucv_callback_txdone(struct iucv_path *, struct iucv_message *); - -static struct iucv_handler netiucv_handler = { - .path_pending = netiucv_callback_connreq, - .path_complete = netiucv_callback_connack, - .path_severed = netiucv_callback_connrej, - .path_quiesced = netiucv_callback_connsusp, - .path_resumed = netiucv_callback_connres, - .message_pending = netiucv_callback_rx, - .message_complete = netiucv_callback_txdone -}; - /** * Per connection profiling data */ @@ -192,8 +92,9 @@ struct connection_profile { * Representation of one iucv connection */ struct iucv_connection { - struct list_head list; - struct iucv_path *path; + struct iucv_connection *next; + iucv_handle_t handle; + __u16 pathid; struct sk_buff *rx_buff; struct sk_buff *tx_buff; struct sk_buff_head collect_queue; @@ -211,9 +112,12 @@ struct iucv_connection { /** * Linked list of all connection structs. */ -static struct list_head iucv_connection_list = - LIST_HEAD_INIT(iucv_connection_list); -static rwlock_t iucv_connection_rwlock = RW_LOCK_UNLOCKED; +struct iucv_connection_struct { + struct iucv_connection *iucv_connections; + rwlock_t iucv_rwlock; +}; + +static struct iucv_connection_struct iucv_conns; /** * Representation of event-data for the @@ -238,11 +142,11 @@ struct netiucv_priv { /** * Link level header for a packet. */ -struct ll_header { - u16 next; -}; +typedef struct ll_header_t { + __u16 next; +} ll_header; -#define NETIUCV_HDRLEN (sizeof(struct ll_header)) +#define NETIUCV_HDRLEN (sizeof(ll_header)) #define NETIUCV_BUFSIZE_MAX 32768 #define NETIUCV_BUFSIZE_DEFAULT NETIUCV_BUFSIZE_MAX #define NETIUCV_MTU_MAX (NETIUCV_BUFSIZE_MAX - NETIUCV_HDRLEN) @@ -254,25 +158,35 @@ struct ll_header { * Compatibility macros for busy handling * of network devices. */ -static inline void netiucv_clear_busy(struct net_device *dev) +static __inline__ void netiucv_clear_busy(struct net_device *dev) { - struct netiucv_priv *priv = netdev_priv(dev); - clear_bit(0, &priv->tbusy); + clear_bit(0, &(((struct netiucv_priv *)dev->priv)->tbusy)); netif_wake_queue(dev); } -static inline int netiucv_test_and_set_busy(struct net_device *dev) +static __inline__ int netiucv_test_and_set_busy(struct net_device *dev) { - struct netiucv_priv *priv = netdev_priv(dev); netif_stop_queue(dev); - return test_and_set_bit(0, &priv->tbusy); + return test_and_set_bit(0, &((struct netiucv_priv *)dev->priv)->tbusy); } -static u8 iucvMagic[16] = { +static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static __u8 iucvMagic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; +/** + * This mask means the 16-byte IUCV "magic" and the origin userid must + * match exactly as specified in order to give connection_pending() + * control. + */ +static __u8 netiucv_mask[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + /** * Convert an iucv userId to its printable * form (strip whitespace at end). @@ -281,7 +195,8 @@ static u8 iucvMagic[16] = { * * @returns The printable string (static data!!) */ -static inline char *netiucv_printname(char *name) +static __inline__ char * +netiucv_printname(char *name) { static char tmp[9]; char *p = tmp; @@ -464,7 +379,8 @@ static debug_info_t *iucv_dbf_trace = NULL; DEFINE_PER_CPU(char[256], iucv_dbf_txt_buf); -static void iucv_unregister_dbf_views(void) +static void +iucv_unregister_dbf_views(void) { if (iucv_dbf_setup) debug_unregister(iucv_dbf_setup); @@ -473,7 +389,8 @@ static void iucv_unregister_dbf_views(void) if (iucv_dbf_trace) debug_unregister(iucv_dbf_trace); } -static int iucv_register_dbf_views(void) +static int +iucv_register_dbf_views(void) { iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME, IUCV_DBF_SETUP_PAGES, @@ -505,111 +422,125 @@ static int iucv_register_dbf_views(void) return 0; } -/* +/** * Callback-wrappers, called from lowlevel iucv layer. - */ + *****************************************************************************/ -static void netiucv_callback_rx(struct iucv_path *path, - struct iucv_message *msg) +static void +netiucv_callback_rx(iucv_MessagePending *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; ev.conn = conn; - ev.data = msg; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_RX, &ev); } -static void netiucv_callback_txdone(struct iucv_path *path, - struct iucv_message *msg) +static void +netiucv_callback_txdone(iucv_MessageComplete *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; ev.conn = conn; - ev.data = msg; + ev.data = (void *)eib; fsm_event(conn->fsm, CONN_EVENT_TXDONE, &ev); } -static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connack(iucv_ConnectionComplete *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, &ev); } -static int netiucv_callback_connreq(struct iucv_path *path, - u8 ipvmid[8], u8 ipuser[16]) +static void +netiucv_callback_connreq(iucv_ConnectionPending *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; struct iucv_event ev; - int rc; - if (memcmp(iucvMagic, ipuser, sizeof(ipuser))) - /* ipuser must match iucvMagic. */ - return -EINVAL; - rc = -EINVAL; - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(conn, &iucv_connection_list, list) { - if (strncmp(ipvmid, conn->userid, 8)) - continue; - /* Found a matching connection for this path. */ - conn->path = path; - ev.conn = conn; - ev.data = path; - fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); - rc = 0; - } - read_unlock_bh(&iucv_connection_rwlock); - return rc; + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REQ, &ev); } -static void netiucv_callback_connrej(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connrej(iucv_ConnectionSevered *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, &ev); } -static void netiucv_callback_connsusp(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connsusp(iucv_ConnectionQuiesced *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn); + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, &ev); } -static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16]) +static void +netiucv_callback_connres(iucv_ConnectionResumed *eib, void *pgm_data) { - struct iucv_connection *conn = path->private; + struct iucv_connection *conn = (struct iucv_connection *)pgm_data; + struct iucv_event ev; - fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn); -} + ev.conn = conn; + ev.data = (void *)eib; + fsm_event(conn->fsm, CONN_EVENT_CONN_RES, &ev); +} + +static iucv_interrupt_ops_t netiucv_ops = { + .ConnectionPending = netiucv_callback_connreq, + .ConnectionComplete = netiucv_callback_connack, + .ConnectionSevered = netiucv_callback_connrej, + .ConnectionQuiesced = netiucv_callback_connsusp, + .ConnectionResumed = netiucv_callback_connres, + .MessagePending = netiucv_callback_rx, + .MessageComplete = netiucv_callback_txdone +}; /** * Dummy NOP action for all statemachines */ -static void fsm_action_nop(fsm_instance *fi, int event, void *arg) +static void +fsm_action_nop(fsm_instance *fi, int event, void *arg) { } -/* +/** * Actions of the connection statemachine - */ + *****************************************************************************/ /** - * netiucv_unpack_skb - * @conn: The connection where this skb has been received. - * @pskb: The received skb. + * Helper function for conn_action_rx() + * Unpack a just received skb and hand it over to + * upper layers. * - * Unpack a just received skb and hand it over to upper layers. - * Helper function for conn_action_rx. + * @param conn The connection where this skb has been received. + * @param pskb The received skb. */ -static void netiucv_unpack_skb(struct iucv_connection *conn, - struct sk_buff *pskb) +//static __inline__ void +static void +netiucv_unpack_skb(struct iucv_connection *conn, struct sk_buff *pskb) { struct net_device *dev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(dev); - u16 offset = 0; + struct netiucv_priv *privptr = dev->priv; + __u16 offset = 0; skb_put(pskb, NETIUCV_HDRLEN); pskb->dev = dev; @@ -618,7 +549,7 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, while (1) { struct sk_buff *skb; - struct ll_header *header = (struct ll_header *) pskb->data; + ll_header *header = (ll_header *)pskb->data; if (!header->next) break; @@ -664,37 +595,40 @@ static void netiucv_unpack_skb(struct iucv_connection *conn, } } -static void conn_action_rx(fsm_instance *fi, int event, void *arg) +static void +conn_action_rx(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_message *msg = ev->data; - struct netiucv_priv *privptr = netdev_priv(conn->netdev); + iucv_MessagePending *eib = (iucv_MessagePending *)ev->data; + struct netiucv_priv *privptr =(struct netiucv_priv *)conn->netdev->priv; + + __u32 msglen = eib->ln1msg2.ipbfln1f; int rc; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); if (!conn->netdev) { - iucv_message_reject(conn->path, msg); + /* FRITZ: How to tell iucv LL to drop the msg? */ PRINT_WARN("Received data for unlinked connection\n"); IUCV_DBF_TEXT(data, 2, - "Received data for unlinked connection\n"); + "Received data for unlinked connection\n"); return; } - if (msg->length > conn->max_buffsize) { - iucv_message_reject(conn->path, msg); + if (msglen > conn->max_buffsize) { + /* FRITZ: How to tell iucv LL to drop the msg? */ privptr->stats.rx_dropped++; PRINT_WARN("msglen %d > max_buffsize %d\n", - msg->length, conn->max_buffsize); + msglen, conn->max_buffsize); IUCV_DBF_TEXT_(data, 2, "msglen %d > max_buffsize %d\n", - msg->length, conn->max_buffsize); + msglen, conn->max_buffsize); return; } conn->rx_buff->data = conn->rx_buff->tail = conn->rx_buff->head; conn->rx_buff->len = 0; - rc = iucv_message_receive(conn->path, msg, 0, conn->rx_buff->data, - msg->length, NULL); - if (rc || msg->length < 5) { + rc = iucv_receive(conn->pathid, eib->ipmsgid, eib->iptrgcls, + conn->rx_buff->data, msglen, NULL, NULL, NULL); + if (rc || msglen < 5) { privptr->stats.rx_errors++; PRINT_WARN("iucv_receive returned %08x\n", rc); IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_receive\n", rc); @@ -703,26 +637,26 @@ static void conn_action_rx(fsm_instance *fi, int event, void *arg) netiucv_unpack_skb(conn, conn->rx_buff); } -static void conn_action_txdone(fsm_instance *fi, int event, void *arg) +static void +conn_action_txdone(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_message *msg = ev->data; - struct iucv_message txmsg; + iucv_MessageComplete *eib = (iucv_MessageComplete *)ev->data; struct netiucv_priv *privptr = NULL; - u32 single_flag = msg->tag; - u32 txbytes = 0; - u32 txpackets = 0; - u32 stat_maxcq = 0; + /* Shut up, gcc! skb is always below 2G. */ + __u32 single_flag = eib->ipmsgtag; + __u32 txbytes = 0; + __u32 txpackets = 0; + __u32 stat_maxcq = 0; struct sk_buff *skb; unsigned long saveflags; - struct ll_header header; - int rc; + ll_header header; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); - if (conn && conn->netdev) - privptr = netdev_priv(conn->netdev); + if (conn && conn->netdev && conn->netdev->priv) + privptr = (struct netiucv_priv *)conn->netdev->priv; conn->prof.tx_pending--; if (single_flag) { if ((skb = skb_dequeue(&conn->commit_queue))) { @@ -754,55 +688,56 @@ static void conn_action_txdone(fsm_instance *fi, int event, void *arg) conn->prof.maxmulti = conn->collect_len; conn->collect_len = 0; spin_unlock_irqrestore(&conn->collect_lock, saveflags); - if (conn->tx_buff->len == 0) { - fsm_newstate(fi, CONN_STATE_IDLE); - return; - } + if (conn->tx_buff->len) { + int rc; + + header.next = 0; + memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, + NETIUCV_HDRLEN); - header.next = 0; - memcpy(skb_put(conn->tx_buff, NETIUCV_HDRLEN), &header, NETIUCV_HDRLEN); - conn->prof.send_stamp = xtime; - txmsg.class = 0; - txmsg.tag = 0; - rc = iucv_message_send(conn->path, &txmsg, 0, 0, + conn->prof.send_stamp = xtime; + rc = iucv_send(conn->pathid, NULL, 0, 0, 0, 0, conn->tx_buff->data, conn->tx_buff->len); - conn->prof.doios_multi++; - conn->prof.txlen += conn->tx_buff->len; - conn->prof.tx_pending++; - if (conn->prof.tx_pending > conn->prof.tx_max_pending) - conn->prof.tx_max_pending = conn->prof.tx_pending; - if (rc) { - conn->prof.tx_pending--; - fsm_newstate(fi, CONN_STATE_IDLE); - if (privptr) - privptr->stats.tx_errors += txpackets; - PRINT_WARN("iucv_send returned %08x\n", rc); - IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); - } else { - if (privptr) { - privptr->stats.tx_packets += txpackets; - privptr->stats.tx_bytes += txbytes; + conn->prof.doios_multi++; + conn->prof.txlen += conn->tx_buff->len; + conn->prof.tx_pending++; + if (conn->prof.tx_pending > conn->prof.tx_max_pending) + conn->prof.tx_max_pending = conn->prof.tx_pending; + if (rc) { + conn->prof.tx_pending--; + fsm_newstate(fi, CONN_STATE_IDLE); + if (privptr) + privptr->stats.tx_errors += txpackets; + PRINT_WARN("iucv_send returned %08x\n", rc); + IUCV_DBF_TEXT_(data, 2, "rc %d from iucv_send\n", rc); + } else { + if (privptr) { + privptr->stats.tx_packets += txpackets; + privptr->stats.tx_bytes += txbytes; + } + if (stat_maxcq > conn->prof.maxcqueue) + conn->prof.maxcqueue = stat_maxcq; } - if (stat_maxcq > conn->prof.maxcqueue) - conn->prof.maxcqueue = stat_maxcq; - } + } else + fsm_newstate(fi, CONN_STATE_IDLE); } -static void conn_action_connaccept(fsm_instance *fi, int event, void *arg) +static void +conn_action_connaccept(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; - struct iucv_path *path = ev->data; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; int rc; + __u16 msglimit; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - conn->path = path; - path->msglim = NETIUCV_QUEUELEN_DEFAULT; - path->flags = 0; - rc = iucv_path_accept(path, &netiucv_handler, NULL, conn); + rc = iucv_accept(eib->ippathid, NETIUCV_QUEUELEN_DEFAULT, udata, 0, + conn->handle, conn, NULL, &msglimit); if (rc) { PRINT_WARN("%s: IUCV accept failed with error %d\n", netdev->name, rc); @@ -810,126 +745,183 @@ static void conn_action_connaccept(fsm_instance *fi, int event, void *arg) return; } fsm_newstate(fi, CONN_STATE_IDLE); - netdev->tx_queue_len = conn->path->msglim; + conn->pathid = eib->ippathid; + netdev->tx_queue_len = msglimit; fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); } -static void conn_action_connreject(fsm_instance *fi, int event, void *arg) +static void +conn_action_connreject(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; - struct iucv_path *path = ev->data; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + struct net_device *netdev = conn->netdev; + iucv_ConnectionPending *eib = (iucv_ConnectionPending *)ev->data; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - iucv_path_sever(path, NULL); + + iucv_sever(eib->ippathid, udata); + if (eib->ippathid != conn->pathid) { + PRINT_INFO("%s: IR Connection Pending; " + "pathid %d does not match original pathid %d\n", + netdev->name, eib->ippathid, conn->pathid); + IUCV_DBF_TEXT_(data, 2, + "connreject: IR pathid %d, conn. pathid %d\n", + eib->ippathid, conn->pathid); + iucv_sever(conn->pathid, udata); + } } -static void conn_action_connack(fsm_instance *fi, int event, void *arg) +static void +conn_action_connack(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + iucv_ConnectionComplete *eib = (iucv_ConnectionComplete *)ev->data; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_IDLE); - netdev->tx_queue_len = conn->path->msglim; + if (eib->ippathid != conn->pathid) { + PRINT_INFO("%s: IR Connection Complete; " + "pathid %d does not match original pathid %d\n", + netdev->name, eib->ippathid, conn->pathid); + IUCV_DBF_TEXT_(data, 2, + "connack: IR pathid %d, conn. pathid %d\n", + eib->ippathid, conn->pathid); + conn->pathid = eib->ippathid; + } + netdev->tx_queue_len = eib->ipmsglim; fsm_event(privptr->fsm, DEV_EVENT_CONUP, netdev); } -static void conn_action_conntimsev(fsm_instance *fi, int event, void *arg) +static void +conn_action_conntimsev(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_connection *conn = (struct iucv_connection *)arg; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + fsm_deltimer(&conn->timer); - iucv_path_sever(conn->path, NULL); + iucv_sever(conn->pathid, udata); fsm_newstate(fi, CONN_STATE_STARTWAIT); } -static void conn_action_connsever(fsm_instance *fi, int event, void *arg) +static void +conn_action_connsever(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; + __u8 udata[16]; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); fsm_deltimer(&conn->timer); - iucv_path_sever(conn->path, NULL); + iucv_sever(conn->pathid, udata); PRINT_INFO("%s: Remote dropped connection\n", netdev->name); IUCV_DBF_TEXT(data, 2, - "conn_action_connsever: Remote dropped connection\n"); + "conn_action_connsever: Remote dropped connection\n"); fsm_newstate(fi, CONN_STATE_STARTWAIT); fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } -static void conn_action_start(fsm_instance *fi, int event, void *arg) +static void +conn_action_start(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; + __u16 msglimit; int rc; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - fsm_newstate(fi, CONN_STATE_STARTWAIT); + if (!conn->handle) { + IUCV_DBF_TEXT(trace, 5, "calling iucv_register_program\n"); + conn->handle = + iucv_register_program(iucvMagic, conn->userid, + netiucv_mask, + &netiucv_ops, conn); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + if (!conn->handle) { + fsm_newstate(fi, CONN_STATE_REGERR); + conn->handle = NULL; + IUCV_DBF_TEXT(setup, 2, + "NULL from iucv_register_program\n"); + return; + } + + PRINT_DEBUG("%s('%s'): registered successfully\n", + conn->netdev->name, conn->userid); + } + PRINT_DEBUG("%s('%s'): connecting ...\n", - conn->netdev->name, conn->userid); + conn->netdev->name, conn->userid); - /* - * We must set the state before calling iucv_connect because the - * callback handler could be called at any point after the connection - * request is sent - */ + /* We must set the state before calling iucv_connect because the callback + * handler could be called at any point after the connection request is + * sent */ fsm_newstate(fi, CONN_STATE_SETUPWAIT); - conn->path = iucv_path_alloc(NETIUCV_QUEUELEN_DEFAULT, 0, GFP_KERNEL); - rc = iucv_path_connect(conn->path, &netiucv_handler, conn->userid, - NULL, iucvMagic, conn); + rc = iucv_connect(&(conn->pathid), NETIUCV_QUEUELEN_DEFAULT, iucvMagic, + conn->userid, iucv_host, 0, NULL, &msglimit, + conn->handle, conn); switch (rc) { - case 0: - conn->netdev->tx_queue_len = conn->path->msglim; - fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, - CONN_EVENT_TIMER, conn); - return; - case 11: - PRINT_INFO("%s: User %s is currently not available.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_STARTWAIT); - break; - case 12: - PRINT_INFO("%s: User %s is currently not ready.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_STARTWAIT); - break; - case 13: - PRINT_WARN("%s: Too many IUCV connections.\n", - conn->netdev->name); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - case 14: - PRINT_WARN("%s: User %s has too many IUCV connections.\n", - conn->netdev->name, - netiucv_printname(conn->userid)); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - case 15: - PRINT_WARN("%s: No IUCV authorization in CP directory.\n", - conn->netdev->name); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; - default: - PRINT_WARN("%s: iucv_connect returned error %d\n", - conn->netdev->name, rc); - fsm_newstate(fi, CONN_STATE_CONNERR); - break; + case 0: + conn->netdev->tx_queue_len = msglimit; + fsm_addtimer(&conn->timer, NETIUCV_TIMEOUT_5SEC, + CONN_EVENT_TIMER, conn); + return; + case 11: + PRINT_INFO("%s: User %s is currently not available.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 12: + PRINT_INFO("%s: User %s is currently not ready.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_STARTWAIT); + return; + case 13: + PRINT_WARN("%s: Too many IUCV connections.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 14: + PRINT_WARN( + "%s: User %s has too many IUCV connections.\n", + conn->netdev->name, + netiucv_printname(conn->userid)); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + case 15: + PRINT_WARN( + "%s: No IUCV authorization in CP directory.\n", + conn->netdev->name); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; + default: + PRINT_WARN("%s: iucv_connect returned error %d\n", + conn->netdev->name, rc); + fsm_newstate(fi, CONN_STATE_CONNERR); + break; } IUCV_DBF_TEXT_(setup, 5, "iucv_connect rc is %d\n", rc); - kfree(conn->path); - conn->path = NULL; + IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); + iucv_unregister_program(conn->handle); + conn->handle = NULL; } -static void netiucv_purge_skb_queue(struct sk_buff_head *q) +static void +netiucv_purge_skb_queue(struct sk_buff_head *q) { struct sk_buff *skb; @@ -939,34 +931,36 @@ static void netiucv_purge_skb_queue(struct sk_buff_head *q) } } -static void conn_action_stop(fsm_instance *fi, int event, void *arg) +static void +conn_action_stop(fsm_instance *fi, int event, void *arg) { - struct iucv_event *ev = arg; + struct iucv_event *ev = (struct iucv_event *)arg; struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - struct netiucv_priv *privptr = netdev_priv(netdev); + struct netiucv_priv *privptr = (struct netiucv_priv *)netdev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); fsm_deltimer(&conn->timer); fsm_newstate(fi, CONN_STATE_STOPPED); netiucv_purge_skb_queue(&conn->collect_queue); - if (conn->path) { - IUCV_DBF_TEXT(trace, 5, "calling iucv_path_sever\n"); - iucv_path_sever(conn->path, iucvMagic); - kfree(conn->path); - conn->path = NULL; - } + if (conn->handle) + IUCV_DBF_TEXT(trace, 5, "calling iucv_unregister_program\n"); + iucv_unregister_program(conn->handle); + conn->handle = NULL; netiucv_purge_skb_queue(&conn->commit_queue); fsm_event(privptr->fsm, DEV_EVENT_CONDOWN, netdev); } -static void conn_action_inval(fsm_instance *fi, int event, void *arg) +static void +conn_action_inval(fsm_instance *fi, int event, void *arg) { - struct iucv_connection *conn = arg; + struct iucv_event *ev = (struct iucv_event *)arg; + struct iucv_connection *conn = ev->conn; struct net_device *netdev = conn->netdev; - PRINT_WARN("%s: Cannot connect without username\n", netdev->name); + PRINT_WARN("%s: Cannot connect without username\n", + netdev->name); IUCV_DBF_TEXT(data, 2, "conn_action_inval called\n"); } @@ -1005,27 +999,29 @@ static const fsm_node conn_fsm[] = { static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); -/* +/** * Actions for interface - statemachine. - */ + *****************************************************************************/ /** - * dev_action_start - * @fi: An instance of an interface statemachine. - * @event: The event, just happened. - * @arg: Generic pointer, casted from struct net_device * upon call. - * * Startup connection by sending CONN_EVENT_START to it. + * + * @param fi An instance of an interface statemachine. + * @param event The event, just happened. + * @param arg Generic pointer, casted from struct net_device * upon call. */ -static void dev_action_start(fsm_instance *fi, int event, void *arg) +static void +dev_action_start(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; + struct iucv_event ev; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); + ev.conn = privptr->conn; fsm_newstate(fi, DEV_STATE_STARTWAIT); - fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn); + fsm_event(privptr->conn->fsm, CONN_EVENT_START, &ev); } /** @@ -1038,8 +1034,8 @@ static void dev_action_start(fsm_instance *fi, int event, void *arg) static void dev_action_stop(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; struct iucv_event ev; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -1061,8 +1057,8 @@ dev_action_stop(fsm_instance *fi, int event, void *arg) static void dev_action_connup(fsm_instance *fi, int event, void *arg) { - struct net_device *dev = arg; - struct netiucv_priv *privptr = netdev_priv(dev); + struct net_device *dev = (struct net_device *)arg; + struct netiucv_priv *privptr = dev->priv; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -1135,13 +1131,11 @@ static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_transmit_skb(struct iucv_connection *conn, - struct sk_buff *skb) -{ - struct iucv_message msg; +static int +netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { unsigned long saveflags; - struct ll_header header; - int rc; + ll_header header; + int rc = 0; if (fsm_getstate(conn->fsm) != CONN_STATE_IDLE) { int l = skb->len + NETIUCV_HDRLEN; @@ -1151,12 +1145,11 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, (conn->max_buffsize - NETIUCV_HDRLEN)) { rc = -EBUSY; IUCV_DBF_TEXT(data, 2, - "EBUSY from netiucv_transmit_skb\n"); + "EBUSY from netiucv_transmit_skb\n"); } else { atomic_inc(&skb->users); skb_queue_tail(&conn->collect_queue, skb); conn->collect_len += l; - rc = 0; } spin_unlock_irqrestore(&conn->collect_lock, saveflags); } else { @@ -1195,10 +1188,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, fsm_newstate(conn->fsm, CONN_STATE_TX); conn->prof.send_stamp = xtime; - msg.tag = 1; - msg.class = 0; - rc = iucv_message_send(conn->path, &msg, 0, 0, - nskb->data, nskb->len); + rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */, + 0, nskb->data, nskb->len); + /* Shut up, gcc! nskb is always below 2G. */ conn->prof.doios_single++; conn->prof.txlen += skb->len; conn->prof.tx_pending++; @@ -1208,7 +1200,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, struct netiucv_priv *privptr; fsm_newstate(conn->fsm, CONN_STATE_IDLE); conn->prof.tx_pending--; - privptr = netdev_priv(conn->netdev); + privptr = (struct netiucv_priv *)conn->netdev->priv; if (privptr) privptr->stats.tx_errors++; if (copied) @@ -1234,9 +1226,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, return rc; } -/* +/** * Interface API for upper network layers - */ + *****************************************************************************/ /** * Open an interface. @@ -1246,11 +1238,9 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_open(struct net_device *dev) -{ - struct netiucv_priv *priv = netdev_priv(dev); - - fsm_event(priv->fsm, DEV_EVENT_START, dev); +static int +netiucv_open(struct net_device *dev) { + fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_START,dev); return 0; } @@ -1262,11 +1252,9 @@ static int netiucv_open(struct net_device *dev) * * @return 0 on success, -ERRNO on failure. (Never fails.) */ -static int netiucv_close(struct net_device *dev) -{ - struct netiucv_priv *priv = netdev_priv(dev); - - fsm_event(priv->fsm, DEV_EVENT_STOP, dev); +static int +netiucv_close(struct net_device *dev) { + fsm_event(((struct netiucv_priv *)dev->priv)->fsm, DEV_EVENT_STOP, dev); return 0; } @@ -1283,8 +1271,8 @@ static int netiucv_close(struct net_device *dev) */ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) { - struct netiucv_priv *privptr = netdev_priv(dev); - int rc; + int rc = 0; + struct netiucv_priv *privptr = dev->priv; IUCV_DBF_TEXT(trace, 4, __FUNCTION__); /** @@ -1324,41 +1312,40 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) return -EBUSY; } dev->trans_start = jiffies; - rc = netiucv_transmit_skb(privptr->conn, skb) != 0; + if (netiucv_transmit_skb(privptr->conn, skb)) + rc = 1; netiucv_clear_busy(dev); return rc; } /** - * netiucv_stats - * @dev: Pointer to interface struct. - * * Returns interface statistics of a device. * - * Returns pointer to stats struct of this interface. + * @param dev Pointer to interface struct. + * + * @return Pointer to stats struct of this interface. */ -static struct net_device_stats *netiucv_stats (struct net_device * dev) +static struct net_device_stats * +netiucv_stats (struct net_device * dev) { - struct netiucv_priv *priv = netdev_priv(dev); - IUCV_DBF_TEXT(trace, 5, __FUNCTION__); - return &priv->stats; + return &((struct netiucv_priv *)dev->priv)->stats; } /** - * netiucv_change_mtu - * @dev: Pointer to interface struct. - * @new_mtu: The new MTU to use for this interface. - * * Sets MTU of an interface. * - * Returns 0 on success, -EINVAL if MTU is out of valid range. + * @param dev Pointer to interface struct. + * @param new_mtu The new MTU to use for this interface. + * + * @return 0 on success, -EINVAL if MTU is out of valid range. * (valid range is 576 .. NETIUCV_MTU_MAX). */ -static int netiucv_change_mtu(struct net_device * dev, int new_mtu) +static int +netiucv_change_mtu (struct net_device * dev, int new_mtu) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - if (new_mtu < 576 || new_mtu > NETIUCV_MTU_MAX) { + if ((new_mtu < 576) || (new_mtu > NETIUCV_MTU_MAX)) { IUCV_DBF_TEXT(setup, 2, "given MTU out of valid range\n"); return -EINVAL; } @@ -1366,12 +1353,12 @@ static int netiucv_change_mtu(struct net_device * dev, int new_mtu) return 0; } -/* +/** * attributes in sysfs - */ + *****************************************************************************/ -static ssize_t user_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +user_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1379,8 +1366,8 @@ static ssize_t user_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%s\n", netiucv_printname(priv->conn->userid)); } -static ssize_t user_write(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +user_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; struct net_device *ndev = priv->conn->netdev; @@ -1388,70 +1375,80 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr, char *tmp; char username[9]; int i; - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - if (count > 9) { - PRINT_WARN("netiucv: username too long (%d)!\n", (int) count); + if (count>9) { + PRINT_WARN("netiucv: username too long (%d)!\n", (int)count); IUCV_DBF_TEXT_(setup, 2, - "%d is length of username\n", (int) count); + "%d is length of username\n", (int)count); return -EINVAL; } tmp = strsep((char **) &buf, "\n"); - for (i = 0, p = tmp; i < 8 && *p; i++, p++) { - if (isalnum(*p) || (*p == '$')) { + for (i=0, p=tmp; i<8 && *p; i++, p++) { + if (isalnum(*p) || (*p == '$')) username[i]= toupper(*p); - continue; - } - if (*p == '\n') { + else if (*p == '\n') { /* trailing lf, grr */ break; + } else { + PRINT_WARN("netiucv: Invalid char %c in username!\n", + *p); + IUCV_DBF_TEXT_(setup, 2, + "username: invalid character %c\n", + *p); + return -EINVAL; } - PRINT_WARN("netiucv: Invalid char %c in username!\n", *p); - IUCV_DBF_TEXT_(setup, 2, - "username: invalid character %c\n", *p); - return -EINVAL; } - while (i < 8) + while (i<8) username[i++] = ' '; username[8] = '\0'; - if (memcmp(username, priv->conn->userid, 9) && - (ndev->flags & (IFF_UP | IFF_RUNNING))) { - /* username changed while the interface is active. */ - PRINT_WARN("netiucv: device %s active, connected to %s\n", - dev->bus_id, priv->conn->userid); - PRINT_WARN("netiucv: user cannot be updated\n"); - IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); - return -EBUSY; - } - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(cp, &iucv_connection_list, list) { - if (!strncmp(username, cp->userid, 9) && cp->netdev != ndev) { - read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); - return -EEXIST; + if (memcmp(username, priv->conn->userid, 9)) { + /* username changed */ + if (ndev->flags & (IFF_UP | IFF_RUNNING)) { + PRINT_WARN( + "netiucv: device %s active, connected to %s\n", + dev->bus_id, priv->conn->userid); + PRINT_WARN("netiucv: user cannot be updated\n"); + IUCV_DBF_TEXT(setup, 2, "user_write: device active\n"); + return -EBUSY; } } - read_unlock_bh(&iucv_connection_rwlock); + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (!strncmp(username, (*clist)->userid, 9) || + ((*clist)->netdev != ndev)) + break; + clist = &((*clist)->next); + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (*clist) { + PRINT_WARN("netiucv: Connection to %s already exists\n", + username); + return -EEXIST; + } memcpy(priv->conn->userid, username, 9); + return count; + } static DEVICE_ATTR(user, 0644, user_show, user_write); -static ssize_t buffer_show (struct device *dev, struct device_attribute *attr, - char *buf) -{ struct netiucv_priv *priv = dev->driver_data; +static ssize_t +buffer_show (struct device *dev, struct device_attribute *attr, char *buf) +{ + struct netiucv_priv *priv = dev->driver_data; IUCV_DBF_TEXT(trace, 5, __FUNCTION__); return sprintf(buf, "%d\n", priv->conn->max_buffsize); } -static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +buffer_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; struct net_device *ndev = priv->conn->netdev; @@ -1505,8 +1502,8 @@ static ssize_t buffer_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); -static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1516,8 +1513,8 @@ static ssize_t dev_fsm_show (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL); -static ssize_t conn_fsm_show (struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1527,8 +1524,8 @@ static ssize_t conn_fsm_show (struct device *dev, static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL); -static ssize_t maxmulti_show (struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1536,9 +1533,8 @@ static ssize_t maxmulti_show (struct device *dev, return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti); } -static ssize_t maxmulti_write (struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +maxmulti_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1549,8 +1545,8 @@ static ssize_t maxmulti_write (struct device *dev, static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write); -static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +maxcq_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1558,8 +1554,8 @@ static ssize_t maxcq_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue); } -static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1570,8 +1566,8 @@ static ssize_t maxcq_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write); -static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +sdoio_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1579,8 +1575,8 @@ static ssize_t sdoio_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.doios_single); } -static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1591,8 +1587,8 @@ static ssize_t sdoio_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write); -static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +mdoio_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1600,8 +1596,8 @@ static ssize_t mdoio_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi); } -static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1612,8 +1608,8 @@ static ssize_t mdoio_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write); -static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txlen_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1621,8 +1617,8 @@ static ssize_t txlen_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.txlen); } -static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1633,8 +1629,8 @@ static ssize_t txlen_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write); -static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txtime_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1642,8 +1638,8 @@ static ssize_t txtime_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_time); } -static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1654,8 +1650,8 @@ static ssize_t txtime_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write); -static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txpend_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1663,8 +1659,8 @@ static ssize_t txpend_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_pending); } -static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txpend_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1675,8 +1671,8 @@ static ssize_t txpend_write (struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write); -static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf) { struct netiucv_priv *priv = dev->driver_data; @@ -1684,8 +1680,8 @@ static ssize_t txmpnd_show (struct device *dev, struct device_attribute *attr, return sprintf(buf, "%ld\n", priv->conn->prof.tx_max_pending); } -static ssize_t txmpnd_write (struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +txmpnd_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct netiucv_priv *priv = dev->driver_data; @@ -1725,7 +1721,8 @@ static struct attribute_group netiucv_stat_attr_group = { .attrs = netiucv_stat_attrs, }; -static inline int netiucv_add_files(struct device *dev) +static inline int +netiucv_add_files(struct device *dev) { int ret; @@ -1739,16 +1736,18 @@ static inline int netiucv_add_files(struct device *dev) return ret; } -static inline void netiucv_remove_files(struct device *dev) +static inline void +netiucv_remove_files(struct device *dev) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); sysfs_remove_group(&dev->kobj, &netiucv_stat_attr_group); sysfs_remove_group(&dev->kobj, &netiucv_attr_group); } -static int netiucv_register_device(struct net_device *ndev) +static int +netiucv_register_device(struct net_device *ndev) { - struct netiucv_priv *priv = netdev_priv(ndev); + struct netiucv_priv *priv = ndev->priv; struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); int ret; @@ -1787,7 +1786,8 @@ static int netiucv_register_device(struct net_device *ndev) return ret; } -static void netiucv_unregister_device(struct device *dev) +static void +netiucv_unregister_device(struct device *dev) { IUCV_DBF_TEXT(trace, 3, __FUNCTION__); netiucv_remove_files(dev); @@ -1798,89 +1798,107 @@ static void netiucv_unregister_device(struct device *dev) * Allocate and initialize a new connection structure. * Add it to the list of netiucv connections; */ -static struct iucv_connection *netiucv_new_connection(struct net_device *dev, - char *username) -{ - struct iucv_connection *conn; +static struct iucv_connection * +netiucv_new_connection(struct net_device *dev, char *username) +{ + unsigned long flags; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + struct iucv_connection *conn = + kzalloc(sizeof(struct iucv_connection), GFP_KERNEL); + + if (conn) { + skb_queue_head_init(&conn->collect_queue); + skb_queue_head_init(&conn->commit_queue); + spin_lock_init(&conn->collect_lock); + conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; + conn->netdev = dev; + + conn->rx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, + GFP_KERNEL | GFP_DMA); + if (!conn->rx_buff) { + kfree(conn); + return NULL; + } + conn->tx_buff = alloc_skb(NETIUCV_BUFSIZE_DEFAULT, + GFP_KERNEL | GFP_DMA); + if (!conn->tx_buff) { + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; + } + conn->fsm = init_fsm("netiucvconn", conn_state_names, + conn_event_names, NR_CONN_STATES, + NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN, + GFP_KERNEL); + if (!conn->fsm) { + kfree_skb(conn->tx_buff); + kfree_skb(conn->rx_buff); + kfree(conn); + return NULL; + } + fsm_settimer(conn->fsm, &conn->timer); + fsm_newstate(conn->fsm, CONN_STATE_INVALID); - conn = kzalloc(sizeof(*conn), GFP_KERNEL); - if (!conn) - goto out; - skb_queue_head_init(&conn->collect_queue); - skb_queue_head_init(&conn->commit_queue); - spin_lock_init(&conn->collect_lock); - conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; - conn->netdev = dev; - - conn->rx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA); - if (!conn->rx_buff) - goto out_conn; - conn->tx_buff = alloc_skb(conn->max_buffsize, GFP_KERNEL | GFP_DMA); - if (!conn->tx_buff) - goto out_rx; - conn->fsm = init_fsm("netiucvconn", conn_state_names, - conn_event_names, NR_CONN_STATES, - NR_CONN_EVENTS, conn_fsm, CONN_FSM_LEN, - GFP_KERNEL); - if (!conn->fsm) - goto out_tx; - - fsm_settimer(conn->fsm, &conn->timer); - fsm_newstate(conn->fsm, CONN_STATE_INVALID); - - if (username) { - memcpy(conn->userid, username, 9); - fsm_newstate(conn->fsm, CONN_STATE_STOPPED); - } + if (username) { + memcpy(conn->userid, username, 9); + fsm_newstate(conn->fsm, CONN_STATE_STOPPED); + } - write_lock_bh(&iucv_connection_rwlock); - list_add_tail(&conn->list, &iucv_connection_list); - write_unlock_bh(&iucv_connection_rwlock); + write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + conn->next = *clist; + *clist = conn; + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + } return conn; - -out_tx: - kfree_skb(conn->tx_buff); -out_rx: - kfree_skb(conn->rx_buff); -out_conn: - kfree(conn); -out: - return NULL; } /** * Release a connection structure and remove it from the * list of netiucv connections. */ -static void netiucv_remove_connection(struct iucv_connection *conn) +static void +netiucv_remove_connection(struct iucv_connection *conn) { + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; + IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - write_lock_bh(&iucv_connection_rwlock); - list_del_init(&conn->list); - write_unlock_bh(&iucv_connection_rwlock); - if (conn->path) { - iucv_path_sever(conn->path, iucvMagic); - kfree(conn->path); - conn->path = NULL; + if (conn == NULL) + return; + write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (*clist == conn) { + *clist = conn->next; + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (conn->handle) { + iucv_unregister_program(conn->handle); + conn->handle = NULL; + } + fsm_deltimer(&conn->timer); + kfree_fsm(conn->fsm); + kfree_skb(conn->rx_buff); + kfree_skb(conn->tx_buff); + return; + } + clist = &((*clist)->next); } - fsm_deltimer(&conn->timer); - kfree_fsm(conn->fsm); - kfree_skb(conn->rx_buff); - kfree_skb(conn->tx_buff); + write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); } /** * Release everything of a net device. */ -static void netiucv_free_netdevice(struct net_device *dev) +static void +netiucv_free_netdevice(struct net_device *dev) { - struct netiucv_priv *privptr = netdev_priv(dev); + struct netiucv_priv *privptr; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); if (!dev) return; + privptr = (struct netiucv_priv *)dev->priv; if (privptr) { if (privptr->conn) netiucv_remove_connection(privptr->conn); @@ -1895,8 +1913,11 @@ static void netiucv_free_netdevice(struct net_device *dev) /** * Initialize a net device. (Called from kernel in alloc_netdev()) */ -static void netiucv_setup_netdevice(struct net_device *dev) +static void +netiucv_setup_netdevice(struct net_device *dev) { + memset(dev->priv, 0, sizeof(struct netiucv_priv)); + dev->mtu = NETIUCV_MTU_DEFAULT; dev->hard_start_xmit = netiucv_tx; dev->open = netiucv_open; @@ -1915,7 +1936,8 @@ static void netiucv_setup_netdevice(struct net_device *dev) /** * Allocate and initialize everything of a net device. */ -static struct net_device *netiucv_init_netdevice(char *username) +static struct net_device * +netiucv_init_netdevice(char *username) { struct netiucv_priv *privptr; struct net_device *dev; @@ -1924,40 +1946,40 @@ static struct net_device *netiucv_init_netdevice(char *username) netiucv_setup_netdevice); if (!dev) return NULL; - if (dev_alloc_name(dev, dev->name) < 0) - goto out_netdev; + if (dev_alloc_name(dev, dev->name) < 0) { + free_netdev(dev); + return NULL; + } - privptr = netdev_priv(dev); + privptr = (struct netiucv_priv *)dev->priv; privptr->fsm = init_fsm("netiucvdev", dev_state_names, dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, dev_fsm, DEV_FSM_LEN, GFP_KERNEL); - if (!privptr->fsm) - goto out_netdev; - + if (!privptr->fsm) { + free_netdev(dev); + return NULL; + } privptr->conn = netiucv_new_connection(dev, username); if (!privptr->conn) { + kfree_fsm(privptr->fsm); + free_netdev(dev); IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_new_connection\n"); - goto out_fsm; + return NULL; } fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); - return dev; -out_fsm: - kfree_fsm(privptr->fsm); -out_netdev: - free_netdev(dev); - return NULL; + return dev; } -static ssize_t conn_write(struct device_driver *drv, - const char *buf, size_t count) +static ssize_t +conn_write(struct device_driver *drv, const char *buf, size_t count) { - const char *p; + char *p; char username[9]; - int i, rc; + int i, ret; struct net_device *dev; - struct netiucv_priv *priv; - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); if (count>9) { @@ -1966,82 +1988,83 @@ static ssize_t conn_write(struct device_driver *drv, return -EINVAL; } - for (i = 0, p = buf; i < 8 && *p; i++, p++) { - if (isalnum(*p) || *p == '$') { - username[i] = toupper(*p); - continue; - } - if (*p == '\n') + for (i=0, p=(char *)buf; i<8 && *p; i++, p++) { + if (isalnum(*p) || (*p == '$')) + username[i]= toupper(*p); + else if (*p == '\n') { /* trailing lf, grr */ break; - PRINT_WARN("netiucv: Invalid character in username!\n"); - IUCV_DBF_TEXT_(setup, 2, - "conn_write: invalid character %c\n", *p); - return -EINVAL; + } else { + PRINT_WARN("netiucv: Invalid character in username!\n"); + IUCV_DBF_TEXT_(setup, 2, + "conn_write: invalid character %c\n", *p); + return -EINVAL; + } } - while (i < 8) + while (i<8) username[i++] = ' '; username[8] = '\0'; - read_lock_bh(&iucv_connection_rwlock); - list_for_each_entry(cp, &iucv_connection_list, list) { - if (!strncmp(username, cp->userid, 9)) { - read_unlock_bh(&iucv_connection_rwlock); - PRINT_WARN("netiucv: Connection to %s already " - "exists\n", username); - return -EEXIST; - } + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + if (!strncmp(username, (*clist)->userid, 9)) + break; + clist = &((*clist)->next); + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); + if (*clist) { + PRINT_WARN("netiucv: Connection to %s already exists\n", + username); + return -EEXIST; } - read_unlock_bh(&iucv_connection_rwlock); - dev = netiucv_init_netdevice(username); if (!dev) { - PRINT_WARN("netiucv: Could not allocate network device " - "structure for user '%s'\n", - netiucv_printname(username)); + PRINT_WARN( + "netiucv: Could not allocate network device structure " + "for user '%s'\n", netiucv_printname(username)); IUCV_DBF_TEXT(setup, 2, "NULL from netiucv_init_netdevice\n"); return -ENODEV; } - rc = netiucv_register_device(dev); - if (rc) { + if ((ret = netiucv_register_device(dev))) { IUCV_DBF_TEXT_(setup, 2, - "ret %d from netiucv_register_device\n", rc); + "ret %d from netiucv_register_device\n", ret); goto out_free_ndev; } /* sysfs magic */ - priv = netdev_priv(dev); - SET_NETDEV_DEV(dev, priv->dev); + SET_NETDEV_DEV(dev, + (struct device*)((struct netiucv_priv*)dev->priv)->dev); - rc = register_netdev(dev); - if (rc) - goto out_unreg; + if ((ret = register_netdev(dev))) { + netiucv_unregister_device((struct device*) + ((struct netiucv_priv*)dev->priv)->dev); + goto out_free_ndev; + } PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username)); return count; -out_unreg: - netiucv_unregister_device(priv->dev); out_free_ndev: PRINT_WARN("netiucv: Could not register '%s'\n", dev->name); IUCV_DBF_TEXT(setup, 2, "conn_write: could not register\n"); netiucv_free_netdevice(dev); - return rc; + return ret; } static DRIVER_ATTR(connection, 0200, NULL, conn_write); -static ssize_t remove_write (struct device_driver *drv, - const char *buf, size_t count) +static ssize_t +remove_write (struct device_driver *drv, const char *buf, size_t count) { - struct iucv_connection *cp; + struct iucv_connection **clist = &iucv_conns.iucv_connections; + unsigned long flags; struct net_device *ndev; struct netiucv_priv *priv; struct device *dev; char name[IFNAMSIZ]; - const char *p; + char *p; int i; IUCV_DBF_TEXT(trace, 3, __FUNCTION__); @@ -2049,27 +2072,33 @@ static ssize_t remove_write (struct device_driver *drv, if (count >= IFNAMSIZ) count = IFNAMSIZ - 1;; - for (i = 0, p = buf; i < count && *p; i++, p++) { - if (*p == '\n' || *p == ' ') + for (i=0, p=(char *)buf; inetdev; - priv = netdev_priv(ndev); + read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); + while (*clist) { + ndev = (*clist)->netdev; + priv = (struct netiucv_priv*)ndev->priv; dev = priv->dev; - if (strncmp(name, ndev->name, count)) - continue; - read_unlock_bh(&iucv_connection_rwlock); + + if (strncmp(name, ndev->name, count)) { + clist = &((*clist)->next); + continue; + } + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); if (ndev->flags & (IFF_UP | IFF_RUNNING)) { - PRINT_WARN("netiucv: net device %s active with peer " - "%s\n", ndev->name, priv->conn->userid); + PRINT_WARN( + "netiucv: net device %s active with peer %s\n", + ndev->name, priv->conn->userid); PRINT_WARN("netiucv: %s cannot be removed\n", - ndev->name); + ndev->name); IUCV_DBF_TEXT(data, 2, "remove_write: still active\n"); return -EBUSY; } @@ -2077,7 +2106,7 @@ static ssize_t remove_write (struct device_driver *drv, netiucv_unregister_device(dev); return count; } - read_unlock_bh(&iucv_connection_rwlock); + read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); PRINT_WARN("netiucv: net device %s unknown\n", name); IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); return -EINVAL; @@ -2085,86 +2114,67 @@ static ssize_t remove_write (struct device_driver *drv, static DRIVER_ATTR(remove, 0200, NULL, remove_write); -static struct attribute * netiucv_drv_attrs[] = { - &driver_attr_connection.attr, - &driver_attr_remove.attr, - NULL, -}; - -static struct attribute_group netiucv_drv_attr_group = { - .attrs = netiucv_drv_attrs, -}; - -static void netiucv_banner(void) +static void +netiucv_banner(void) { PRINT_INFO("NETIUCV driver initialized\n"); } -static void __exit netiucv_exit(void) +static void __exit +netiucv_exit(void) { - struct iucv_connection *cp; - struct net_device *ndev; - struct netiucv_priv *priv; - struct device *dev; - IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - while (!list_empty(&iucv_connection_list)) { - cp = list_entry(iucv_connection_list.next, - struct iucv_connection, list); - list_del(&cp->list); - ndev = cp->netdev; - priv = netdev_priv(ndev); - dev = priv->dev; + while (iucv_conns.iucv_connections) { + struct net_device *ndev = iucv_conns.iucv_connections->netdev; + struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv; + struct device *dev = priv->dev; unregister_netdev(ndev); netiucv_unregister_device(dev); } - sysfs_remove_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); + driver_remove_file(&netiucv_driver, &driver_attr_connection); + driver_remove_file(&netiucv_driver, &driver_attr_remove); driver_unregister(&netiucv_driver); - iucv_unregister(&netiucv_handler, 1); iucv_unregister_dbf_views(); PRINT_INFO("NETIUCV driver unloaded\n"); return; } -static int __init netiucv_init(void) +static int __init +netiucv_init(void) { - int rc; + int ret; - rc = iucv_register_dbf_views(); - if (rc) - goto out; - rc = iucv_register(&netiucv_handler, 1); - if (rc) - goto out_dbf; + ret = iucv_register_dbf_views(); + if (ret) { + PRINT_WARN("netiucv_init failed, " + "iucv_register_dbf_views rc = %d\n", ret); + return ret; + } IUCV_DBF_TEXT(trace, 3, __FUNCTION__); - rc = driver_register(&netiucv_driver); - if (rc) { + ret = driver_register(&netiucv_driver); + if (ret) { PRINT_ERR("NETIUCV: failed to register driver.\n"); - IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); - goto out_iucv; + IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", ret); + iucv_unregister_dbf_views(); + return ret; } - rc = sysfs_create_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); - if (rc) { - PRINT_ERR("NETIUCV: failed to add driver attributes.\n"); - IUCV_DBF_TEXT_(setup, 2, - "ret %d - netiucv_drv_attr_group\n", rc); - goto out_driver; + /* Add entry for specifying connections. */ + ret = driver_create_file(&netiucv_driver, &driver_attr_connection); + if (!ret) { + ret = driver_create_file(&netiucv_driver, &driver_attr_remove); + netiucv_banner(); + rwlock_init(&iucv_conns.iucv_rwlock); + } else { + PRINT_ERR("NETIUCV: failed to add driver attribute.\n"); + IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret); + driver_unregister(&netiucv_driver); + iucv_unregister_dbf_views(); } - netiucv_banner(); - return rc; - -out_driver: - driver_unregister(&netiucv_driver); -out_iucv: - iucv_unregister(&netiucv_handler, 1); -out_dbf: - iucv_unregister_dbf_views(); -out: - return rc; + return ret; } module_init(netiucv_init); diff --git a/trunk/drivers/s390/net/smsgiucv.c b/trunk/drivers/s390/net/smsgiucv.c index 3ccca5871fdf..b8179c27ceb6 100644 --- a/trunk/drivers/s390/net/smsgiucv.c +++ b/trunk/drivers/s390/net/smsgiucv.c @@ -1,7 +1,7 @@ /* * IUCV special message driver * - * Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) * * This program is free software; you can redistribute it and/or modify @@ -23,10 +23,10 @@ #include #include #include -#include #include #include -#include "smsgiucv.h" + +#include "iucv.h" struct smsg_callback { struct list_head list; @@ -39,46 +39,38 @@ MODULE_AUTHOR ("(C) 2003 IBM Corporation by Martin Schwidefsky (schwidefsky@de.ibm.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver"); -static struct iucv_path *smsg_path; - +static iucv_handle_t smsg_handle; +static unsigned short smsg_pathid; static DEFINE_SPINLOCK(smsg_list_lock); static struct list_head smsg_list = LIST_HEAD_INIT(smsg_list); -static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); -static void smsg_message_pending(struct iucv_path *, struct iucv_message *); - -static struct iucv_handler smsg_handler = { - .path_pending = smsg_path_pending, - .message_pending = smsg_message_pending, -}; - -static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], - u8 ipuser[16]) +static void +smsg_connection_complete(iucv_ConnectionComplete *eib, void *pgm_data) { - if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0) - return -EINVAL; - /* Path pending from *MSG. */ - return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); } -static void smsg_message_pending(struct iucv_path *path, - struct iucv_message *msg) + +static void +smsg_message_pending(iucv_MessagePending *eib, void *pgm_data) { struct smsg_callback *cb; - unsigned char *buffer; + unsigned char *msg; unsigned char sender[9]; + unsigned short len; int rc, i; - buffer = kmalloc(msg->length + 1, GFP_ATOMIC | GFP_DMA); - if (!buffer) { - iucv_message_reject(path, msg); + len = eib->ln1msg2.ipbfln1f; + msg = kmalloc(len + 1, GFP_ATOMIC|GFP_DMA); + if (!msg) { + iucv_reject(eib->ippathid, eib->ipmsgid, eib->iptrgcls); return; } - rc = iucv_message_receive(path, msg, 0, buffer, msg->length, NULL); + rc = iucv_receive(eib->ippathid, eib->ipmsgid, eib->iptrgcls, + msg, len, NULL, NULL, NULL); if (rc == 0) { - buffer[msg->length] = 0; - EBCASC(buffer, msg->length); - memcpy(sender, buffer, 8); + msg[len] = 0; + EBCASC(msg, len); + memcpy(sender, msg, 8); sender[8] = 0; /* Remove trailing whitespace from the sender name. */ for (i = 7; i >= 0; i--) { @@ -88,17 +80,27 @@ static void smsg_message_pending(struct iucv_path *path, } spin_lock(&smsg_list_lock); list_for_each_entry(cb, &smsg_list, list) - if (strncmp(buffer + 8, cb->prefix, cb->len) == 0) { - cb->callback(sender, buffer + 8); + if (strncmp(msg + 8, cb->prefix, cb->len) == 0) { + cb->callback(sender, msg + 8); break; } spin_unlock(&smsg_list_lock); } - kfree(buffer); + kfree(msg); } -int smsg_register_callback(char *prefix, - void (*callback)(char *from, char *str)) +static iucv_interrupt_ops_t smsg_ops = { + .ConnectionComplete = smsg_connection_complete, + .MessagePending = smsg_message_pending, +}; + +static struct device_driver smsg_driver = { + .name = "SMSGIUCV", + .bus = &iucv_bus, +}; + +int +smsg_register_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb; @@ -108,18 +110,18 @@ int smsg_register_callback(char *prefix, cb->prefix = prefix; cb->len = strlen(prefix); cb->callback = callback; - spin_lock_bh(&smsg_list_lock); + spin_lock(&smsg_list_lock); list_add_tail(&cb->list, &smsg_list); - spin_unlock_bh(&smsg_list_lock); + spin_unlock(&smsg_list_lock); return 0; } -void smsg_unregister_callback(char *prefix, - void (*callback)(char *from, char *str)) +void +smsg_unregister_callback(char *prefix, void (*callback)(char *from, char *str)) { struct smsg_callback *cb, *tmp; - spin_lock_bh(&smsg_list_lock); + spin_lock(&smsg_list_lock); cb = NULL; list_for_each_entry(tmp, &smsg_list, list) if (tmp->callback == callback && @@ -128,58 +130,55 @@ void smsg_unregister_callback(char *prefix, list_del(&cb->list); break; } - spin_unlock_bh(&smsg_list_lock); + spin_unlock(&smsg_list_lock); kfree(cb); } -static struct device_driver smsg_driver = { - .name = "SMSGIUCV", - .bus = &iucv_bus, -}; - -static void __exit smsg_exit(void) +static void __exit +smsg_exit(void) { - cpcmd("SET SMSG IUCV", NULL, 0, NULL); - iucv_unregister(&smsg_handler, 1); - driver_unregister(&smsg_driver); + if (smsg_handle > 0) { + cpcmd("SET SMSG OFF", NULL, 0, NULL); + iucv_sever(smsg_pathid, NULL); + iucv_unregister_program(smsg_handle); + driver_unregister(&smsg_driver); + } + return; } -static int __init smsg_init(void) +static int __init +smsg_init(void) { + static unsigned char pgmmask[24] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; int rc; rc = driver_register(&smsg_driver); - if (rc != 0) - goto out; - rc = iucv_register(&smsg_handler, 1); - if (rc) { - printk(KERN_ERR "SMSGIUCV: failed to register to iucv"); - rc = -EIO; /* better errno ? */ - goto out_driver; + if (rc != 0) { + printk(KERN_ERR "SMSGIUCV: failed to register driver.\n"); + return rc; } - smsg_path = iucv_path_alloc(255, 0, GFP_KERNEL); - if (!smsg_path) { - rc = -ENOMEM; - goto out_register; + smsg_handle = iucv_register_program("SMSGIUCV ", "*MSG ", + pgmmask, &smsg_ops, NULL); + if (!smsg_handle) { + printk(KERN_ERR "SMSGIUCV: failed to register to iucv"); + driver_unregister(&smsg_driver); + return -EIO; /* better errno ? */ } - rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", - NULL, NULL, NULL); + rc = iucv_connect (&smsg_pathid, 255, NULL, "*MSG ", NULL, 0, + NULL, NULL, smsg_handle, NULL); if (rc) { printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); - rc = -EIO; /* better errno ? */ - goto out_free; + iucv_unregister_program(smsg_handle); + driver_unregister(&smsg_driver); + smsg_handle = NULL; + return -EIO; } cpcmd("SET SMSG IUCV", NULL, 0, NULL); return 0; - -out_free: - iucv_path_free(smsg_path); -out_register: - iucv_unregister(&smsg_handler, 1); -out_driver: - driver_unregister(&smsg_driver); -out: - return rc; } module_init(smsg_init); diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 8f55e1431433..437684084377 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -1375,7 +1375,7 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) } BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE); - if (mtask->hdr->itt == RESERVED_ITT) { + if (mtask->hdr->itt == cpu_to_be32(ISCSI_RESERVED_TAG)) { struct iscsi_session *session = conn->session; spin_lock_bh(&session->lock); diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 7c75771c77ff..d37048c96eab 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -113,7 +113,8 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) hdr->opcode = ISCSI_OP_SCSI_CMD; hdr->flags = ISCSI_ATTR_SIMPLE; int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); - hdr->itt = build_itt(ctask->itt, conn->id, session->age); + hdr->itt = ctask->itt | (conn->id << ISCSI_CID_SHIFT) | + (session->age << ISCSI_AGE_SHIFT); hdr->data_length = cpu_to_be32(sc->request_bufflen); hdr->cmdsn = cpu_to_be32(session->cmdsn); session->cmdsn++; @@ -269,7 +270,7 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - senselen = be16_to_cpu(*(__be16 *)data); + senselen = be16_to_cpu(*(uint16_t *)data); if (datalen < senselen) goto invalid_datalen; @@ -337,7 +338,7 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) { memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr)); - itt = get_itt(rejected_pdu.itt); + itt = rejected_pdu.itt & ISCSI_ITT_MASK; printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected " "due to DataDigest error.\n", itt, rejected_pdu.opcode); @@ -366,10 +367,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_mgmt_task *mtask; uint32_t itt; - if (hdr->itt != RESERVED_ITT) - itt = get_itt(hdr->itt); + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) + itt = hdr->itt & ISCSI_ITT_MASK; else - itt = ~0U; + itt = hdr->itt; if (itt < session->cmds_max) { ctask = session->cmds[itt]; @@ -439,7 +440,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, iscsi_tmf_rsp(conn, hdr); break; case ISCSI_OP_NOOP_IN: - if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) { + if (hdr->ttt != ISCSI_RESERVED_TAG || datalen) { rc = ISCSI_ERR_PROTO; break; } @@ -456,7 +457,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, rc = ISCSI_ERR_BAD_OPCODE; break; } - } else if (itt == ~0U) { + } else if (itt == ISCSI_RESERVED_TAG) { rc = iscsi_check_assign_cmdsn(session, (struct iscsi_nopin*)hdr); if (rc) @@ -469,7 +470,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, break; } - if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) + if (hdr->ttt == ISCSI_RESERVED_TAG) break; if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0)) @@ -515,24 +516,24 @@ int iscsi_verify_itt(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_cmd_task *ctask; uint32_t itt; - if (hdr->itt != RESERVED_ITT) { - if (((__force u32)hdr->itt & ISCSI_AGE_MASK) != + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if ((hdr->itt & ISCSI_AGE_MASK) != (session->age << ISCSI_AGE_SHIFT)) { printk(KERN_ERR "iscsi: received itt %x expected " - "session age (%x)\n", (__force u32)hdr->itt, + "session age (%x)\n", hdr->itt, session->age & ISCSI_AGE_MASK); return ISCSI_ERR_BAD_ITT; } - if (((__force u32)hdr->itt & ISCSI_CID_MASK) != + if ((hdr->itt & ISCSI_CID_MASK) != (conn->id << ISCSI_CID_SHIFT)) { printk(KERN_ERR "iscsi: received itt %x, expected " - "CID (%x)\n", (__force u32)hdr->itt, conn->id); + "CID (%x)\n", hdr->itt, conn->id); return ISCSI_ERR_BAD_ITT; } - itt = get_itt(hdr->itt); + itt = hdr->itt & ISCSI_ITT_MASK; } else - itt = ~0U; + itt = hdr->itt; if (itt < session->cmds_max) { ctask = session->cmds[itt]; @@ -895,8 +896,9 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, /* * pre-format CmdSN for outgoing PDU. */ - if (hdr->itt != RESERVED_ITT) { - hdr->itt = build_itt(mtask->itt, conn->id, session->age); + if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + hdr->itt = mtask->itt | (conn->id << ISCSI_CID_SHIFT) | + (session->age << ISCSI_AGE_SHIFT); nop->cmdsn = cpu_to_be32(session->cmdsn); if (conn->c_stage == ISCSI_CONN_STARTED && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) @@ -1062,7 +1064,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, spin_lock_bh(&session->lock); ctask->mtask = (struct iscsi_mgmt_task *) - session->mgmt_cmds[get_itt(hdr->itt) - + session->mgmt_cmds[(hdr->itt & ISCSI_ITT_MASK) - ISCSI_MGMT_ITT_OFFSET]; if (conn->tmabort_state == TMABORT_INITIAL) { diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index bd6bbf61adb8..7d2311067903 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -521,10 +521,10 @@ static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_ break; default: ; /* probably FILL */ } - aux->filemark_cnt = htonl(STp->filemark_cnt); - aux->phys_fm = htonl(0xffffffff); - aux->last_mark_ppos = htonl(STp->last_mark_ppos); - aux->last_mark_lbn = htonl(STp->last_mark_lbn); + aux->filemark_cnt = ntohl(STp->filemark_cnt); + aux->phys_fm = ntohl(0xffffffff); + aux->last_mark_ppos = ntohl(STp->last_mark_ppos); + aux->last_mark_lbn = ntohl(STp->last_mark_lbn); } /* diff --git a/trunk/drivers/scsi/osst.h b/trunk/drivers/scsi/osst.h index 2cc7b5a1606a..1e426f5d0ed8 100644 --- a/trunk/drivers/scsi/osst.h +++ b/trunk/drivers/scsi/osst.h @@ -288,11 +288,11 @@ typedef struct { #else #error "Please fix " #endif - __be16 max_speed; /* Maximum speed supported in KBps */ + u16 max_speed; /* Maximum speed supported in KBps */ u8 reserved10, reserved11; - __be16 ctl; /* Continuous Transfer Limit in blocks */ - __be16 speed; /* Current Speed, in KBps */ - __be16 buffer_size; /* Buffer Size, in 512 bytes */ + u16 ctl; /* Continuous Transfer Limit in blocks */ + u16 speed; /* Current Speed, in KBps */ + u16 buffer_size; /* Buffer Size, in 512 bytes */ u8 reserved18, reserved19; } osst_capabilities_page_t; @@ -352,8 +352,8 @@ typedef struct { u8 reserved2; u8 density; u8 reserved3,reserved4; - __be16 segtrk; - __be16 trks; + u16 segtrk; + u16 trks; u8 reserved5,reserved6,reserved7,reserved8,reserved9,reserved10; } osst_tape_paramtr_page_t; @@ -369,18 +369,18 @@ typedef struct { typedef struct os_partition_s { __u8 partition_num; __u8 par_desc_ver; - __be16 wrt_pass_cntr; - __be32 first_frame_ppos; - __be32 last_frame_ppos; - __be32 eod_frame_ppos; + __u16 wrt_pass_cntr; + __u32 first_frame_ppos; + __u32 last_frame_ppos; + __u32 eod_frame_ppos; } os_partition_t; /* * DAT entry */ typedef struct os_dat_entry_s { - __be32 blk_sz; - __be16 blk_cnt; + __u32 blk_sz; + __u16 blk_cnt; __u8 flags; __u8 reserved; } os_dat_entry_t; @@ -412,23 +412,23 @@ typedef struct os_dat_s { * AUX */ typedef struct os_aux_s { - __be32 format_id; /* hardware compability AUX is based on */ + __u32 format_id; /* hardware compability AUX is based on */ char application_sig[4]; /* driver used to write this media */ - __be32 hdwr; /* reserved */ - __be32 update_frame_cntr; /* for configuration frame */ + __u32 hdwr; /* reserved */ + __u32 update_frame_cntr; /* for configuration frame */ __u8 frame_type; __u8 frame_type_reserved; __u8 reserved_18_19[2]; os_partition_t partition; __u8 reserved_36_43[8]; - __be32 frame_seq_num; - __be32 logical_blk_num_high; - __be32 logical_blk_num; + __u32 frame_seq_num; + __u32 logical_blk_num_high; + __u32 logical_blk_num; os_dat_t dat; __u8 reserved188_191[4]; - __be32 filemark_cnt; - __be32 phys_fm; - __be32 last_mark_ppos; + __u32 filemark_cnt; + __u32 phys_fm; + __u32 last_mark_ppos; __u8 reserved204_223[20]; /* @@ -436,8 +436,8 @@ typedef struct os_aux_s { * * Linux specific fields: */ - __be32 next_mark_ppos; /* when known, points to next marker */ - __be32 last_mark_lbn; /* storing log_blk_num of last mark is extends ADR spec */ + __u32 next_mark_ppos; /* when known, points to next marker */ + __u32 last_mark_lbn; /* storing log_blk_num of last mark is extends ADR spec */ __u8 linux_specific[24]; __u8 reserved_256_511[256]; @@ -450,19 +450,19 @@ typedef struct os_fm_tab_s { __u8 reserved_1; __u8 fm_tab_ent_sz; __u8 reserved_3; - __be16 fm_tab_ent_cnt; + __u16 fm_tab_ent_cnt; __u8 reserved6_15[10]; - __be32 fm_tab_ent[OS_FM_TAB_MAX]; + __u32 fm_tab_ent[OS_FM_TAB_MAX]; } os_fm_tab_t; typedef struct os_ext_trk_ey_s { __u8 et_part_num; __u8 fmt; - __be16 fm_tab_off; + __u16 fm_tab_off; __u8 reserved4_7[4]; - __be32 last_hlb_hi; - __be32 last_hlb; - __be32 last_pp; + __u32 last_hlb_hi; + __u32 last_hlb; + __u32 last_pp; __u8 reserved20_31[12]; } os_ext_trk_ey_t; @@ -479,17 +479,17 @@ typedef struct os_header_s { char ident_str[8]; __u8 major_rev; __u8 minor_rev; - __be16 ext_trk_tb_off; + __u16 ext_trk_tb_off; __u8 reserved12_15[4]; __u8 pt_par_num; __u8 pt_reserved1_3[3]; os_partition_t partition[16]; - __be32 cfg_col_width; - __be32 dat_col_width; - __be32 qfa_col_width; + __u32 cfg_col_width; + __u32 dat_col_width; + __u32 qfa_col_width; __u8 cartridge[16]; __u8 reserved304_511[208]; - __be32 old_filemark_list[16680/4]; /* in ADR 1.4 __u8 track_table[16680] */ + __u32 old_filemark_list[16680/4]; /* in ADR 1.4 __u8 track_table[16680] */ os_ext_trk_tb_t ext_track_tb; __u8 reserved17272_17735[464]; os_fm_tab_t dat_fm_tab; diff --git a/trunk/drivers/serial/uartlite.c b/trunk/drivers/serial/uartlite.c index f5051cf1a0c8..db8607e3d531 100644 --- a/trunk/drivers/serial/uartlite.c +++ b/trunk/drivers/serial/uartlite.c @@ -256,7 +256,7 @@ static void ulite_release_port(struct uart_port *port) { release_mem_region(port->mapbase, ULITE_REGION); iounmap(port->membase); - port->membase = NULL; + port->membase = 0; } static int ulite_request_port(struct uart_port *port) @@ -438,7 +438,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) port->iotype = UPIO_MEM; port->iobase = 1; /* mark port in use */ port->mapbase = res->start; - port->membase = NULL; + port->membase = 0; port->ops = &ulite_ops; port->irq = res2->start; port->flags = UPF_BOOT_AUTOCONF; @@ -462,7 +462,7 @@ static int ulite_remove(struct platform_device *pdev) uart_remove_one_port(&ulite_uart_driver, port); /* mark port as free */ - port->membase = NULL; + port->membase = 0; return 0; } diff --git a/trunk/drivers/tc/Makefile b/trunk/drivers/tc/Makefile index 83b5bd75ce26..967342692211 100644 --- a/trunk/drivers/tc/Makefile +++ b/trunk/drivers/tc/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-$(CONFIG_TC) += tc.o +obj-$(CONFIG_TC) += tc.o tc-driver.o obj-$(CONFIG_ZS) += zs.o obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o diff --git a/trunk/drivers/tc/tc-driver.c b/trunk/drivers/tc/tc-driver.c new file mode 100644 index 000000000000..16b5bae63c74 --- /dev/null +++ b/trunk/drivers/tc/tc-driver.c @@ -0,0 +1,110 @@ +/* + * TURBOchannel driver services. + * + * Copyright (c) 2005 James Simmons + * Copyright (c) 2006 Maciej W. Rozycki + * + * Loosely based on drivers/dio/dio-driver.c and + * drivers/pci/pci-driver.c. + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + */ + +#include +#include +#include + +/** + * tc_register_driver - register a new TC driver + * @drv: the driver structure to register + * + * Adds the driver structure to the list of registered drivers + * Returns a negative value on error, otherwise 0. + * If no error occurred, the driver remains registered even if + * no device was claimed during registration. + */ +int tc_register_driver(struct tc_driver *tdrv) +{ + return driver_register(&tdrv->driver); +} +EXPORT_SYMBOL(tc_register_driver); + +/** + * tc_unregister_driver - unregister a TC driver + * @drv: the driver structure to unregister + * + * Deletes the driver structure from the list of registered TC drivers, + * gives it a chance to clean up by calling its remove() function for + * each device it was responsible for, and marks those devices as + * driverless. + */ +void tc_unregister_driver(struct tc_driver *tdrv) +{ + driver_unregister(&tdrv->driver); +} +EXPORT_SYMBOL(tc_unregister_driver); + +/** + * tc_match_device - tell if a TC device structure has a matching + * TC device ID structure + * @tdrv: the TC driver to earch for matching TC device ID strings + * @tdev: the TC device structure to match against + * + * Used by a driver to check whether a TC device present in the + * system is in its list of supported devices. Returns the matching + * tc_device_id structure or %NULL if there is no match. + */ +const struct tc_device_id *tc_match_device(struct tc_driver *tdrv, + struct tc_dev *tdev) +{ + const struct tc_device_id *id = tdrv->id_table; + + if (id) { + while (id->name[0] || id->vendor[0]) { + if (strcmp(tdev->name, id->name) == 0 && + strcmp(tdev->vendor, id->vendor) == 0) + return id; + id++; + } + } + return NULL; +} +EXPORT_SYMBOL(tc_match_device); + +/** + * tc_bus_match - Tell if a device structure has a matching + * TC device ID structure + * @dev: the device structure to match against + * @drv: the device driver to search for matching TC device ID strings + * + * Used by a driver to check whether a TC device present in the + * system is in its list of supported devices. Returns 1 if there + * is a match or 0 otherwise. + */ +static int tc_bus_match(struct device *dev, struct device_driver *drv) +{ + struct tc_dev *tdev = to_tc_dev(dev); + struct tc_driver *tdrv = to_tc_driver(drv); + const struct tc_device_id *id; + + id = tc_match_device(tdrv, tdev); + if (id) + return 1; + + return 0; +} + +struct bus_type tc_bus_type = { + .name = "tc", + .match = tc_bus_match, +}; +EXPORT_SYMBOL(tc_bus_type); + +static int __init tc_driver_init(void) +{ + return bus_register(&tc_bus_type); +} + +postcore_initcall(tc_driver_init); diff --git a/trunk/drivers/tc/tc.c b/trunk/drivers/tc/tc.c index 4a51e56f85b6..5514e5283616 100644 --- a/trunk/drivers/tc/tc.c +++ b/trunk/drivers/tc/tc.c @@ -1,254 +1,193 @@ /* - * tc-init: We assume the TURBOchannel to be up and running so - * just probe for Modules and fill in the global data structure - * tc_bus. + * TURBOchannel bus services. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * Copyright (c) Harald Koerfgen, 1998 + * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki + * Copyright (c) 2005 James Simmons * - * Copyright (c) Harald Koerfgen, 1998 - * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. */ +#include +#include #include +#include #include +#include #include #include +#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -slot_info tc_bus[MAX_SLOT]; -static int num_tcslots; -static tcinfo *info; +static struct tc_bus tc_bus = { + .name = "TURBOchannel", +}; /* - * Interface to the world. Read comment in include/asm-mips/tc.h. + * Probing for TURBOchannel modules. */ - -int search_tc_card(const char *name) -{ - int slot; - slot_info *sip; - - for (slot = 0; slot < num_tcslots; slot++) { - sip = &tc_bus[slot]; - if ((sip->flags & FREE) && - (strncmp(sip->name, name, strlen(name)) == 0)) { - return slot; - } - } - - return -ENODEV; -} - -void claim_tc_card(int slot) -{ - if (tc_bus[slot].flags & IN_USE) { - printk("claim_tc_card: attempting to claim a card already in use\n"); - return; - } - tc_bus[slot].flags &= ~FREE; - tc_bus[slot].flags |= IN_USE; -} - -void release_tc_card(int slot) +static void __init tc_bus_add_devices(struct tc_bus *tbus) { - if (tc_bus[slot].flags & FREE) { - printk("release_tc_card: " - "attempting to release a card already free\n"); - return; - } - tc_bus[slot].flags &= ~IN_USE; - tc_bus[slot].flags |= FREE; -} - -unsigned long get_tc_base_addr(int slot) -{ - return tc_bus[slot].base_addr; -} - -unsigned long get_tc_irq_nr(int slot) -{ - return tc_bus[slot].interrupt; -} - -unsigned long get_tc_speed(void) -{ - return 100000 * (10000 / (unsigned long)info->clk_period); -} - -/* - * Probing for TURBOchannel modules - */ -static void __init tc_probe(unsigned long startaddr, unsigned long size, - int slots) -{ - unsigned long slotaddr; + resource_size_t slotsize = tbus->info.slot_size << 20; + resource_size_t extslotsize = tbus->ext_slot_size; + resource_size_t slotaddr; + resource_size_t extslotaddr; + resource_size_t devsize; + void __iomem *module; + struct tc_dev *tdev; int i, slot, err; - long offset; u8 pattern[4]; - volatile u8 *module; + long offset; - for (slot = 0; slot < slots; slot++) { - slotaddr = startaddr + slot * size; - module = ioremap_nocache(slotaddr, size); + for (slot = 0; slot < tbus->num_tcslots; slot++) { + slotaddr = tbus->slot_base + slot * slotsize; + extslotaddr = tbus->ext_slot_base + slot * extslotsize; + module = ioremap_nocache(slotaddr, slotsize); BUG_ON(!module); - offset = OLDCARD; + offset = TC_OLDCARD; err = 0; - err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0); - err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1); - err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2); - err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3); - if (err) { - iounmap(module); - continue; - } + err |= tc_preadb(pattern + 0, module + offset + TC_PATTERN0); + err |= tc_preadb(pattern + 1, module + offset + TC_PATTERN1); + err |= tc_preadb(pattern + 2, module + offset + TC_PATTERN2); + err |= tc_preadb(pattern + 3, module + offset + TC_PATTERN3); + if (err) + goto out_err; if (pattern[0] != 0x55 || pattern[1] != 0x00 || pattern[2] != 0xaa || pattern[3] != 0xff) { - offset = NEWCARD; + offset = TC_NEWCARD; err = 0; - err |= get_dbe(pattern[0], module + TC_PATTERN0); - err |= get_dbe(pattern[1], module + TC_PATTERN1); - err |= get_dbe(pattern[2], module + TC_PATTERN2); - err |= get_dbe(pattern[3], module + TC_PATTERN3); - if (err) { - iounmap(module); - continue; - } + err |= tc_preadb(pattern + 0, + module + offset + TC_PATTERN0); + err |= tc_preadb(pattern + 1, + module + offset + TC_PATTERN1); + err |= tc_preadb(pattern + 2, + module + offset + TC_PATTERN2); + err |= tc_preadb(pattern + 3, + module + offset + TC_PATTERN3); + if (err) + goto out_err; } if (pattern[0] != 0x55 || pattern[1] != 0x00 || - pattern[2] != 0xaa || pattern[3] != 0xff) { - iounmap(module); - continue; + pattern[2] != 0xaa || pattern[3] != 0xff) + goto out_err; + + /* Found a board, allocate it an entry in the list */ + tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); + if (!tdev) { + printk(KERN_ERR "tc%x: unable to allocate tc_dev\n", + slot); + goto out_err; } + sprintf(tdev->dev.bus_id, "tc%x", slot); + tdev->bus = tbus; + tdev->dev.parent = &tbus->dev; + tdev->dev.bus = &tc_bus_type; + tdev->slot = slot; - tc_bus[slot].base_addr = slotaddr; for (i = 0; i < 8; i++) { - tc_bus[slot].firmware[i] = - module[TC_FIRM_VER + offset + 4 * i]; - tc_bus[slot].vendor[i] = - module[TC_VENDOR + offset + 4 * i]; - tc_bus[slot].name[i] = - module[TC_MODULE + offset + 4 * i]; + tdev->firmware[i] = + readb(module + offset + TC_FIRM_VER + 4 * i); + tdev->vendor[i] = + readb(module + offset + TC_VENDOR + 4 * i); + tdev->name[i] = + readb(module + offset + TC_MODULE + 4 * i); } - tc_bus[slot].firmware[8] = 0; - tc_bus[slot].vendor[8] = 0; - tc_bus[slot].name[8] = 0; - /* - * Looks unneccesary, but we may change - * TC? in the future - */ - switch (slot) { - case 0: - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0]; - break; - case 1: - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1]; - break; - case 2: - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2]; - break; - /* - * Yuck! DS5000/200 onboard devices - */ - case 5: - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5]; - break; - case 6: - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6]; - break; - default: - tc_bus[slot].interrupt = -1; - break; + tdev->firmware[8] = 0; + tdev->vendor[8] = 0; + tdev->name[8] = 0; + + pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor, + tdev->name, tdev->firmware); + + devsize = readb(module + offset + TC_SLOT_SIZE); + devsize <<= 22; + if (devsize <= slotsize) { + tdev->resource.start = slotaddr; + tdev->resource.end = slotaddr + devsize - 1; + } else if (devsize <= extslotsize) { + tdev->resource.start = extslotaddr; + tdev->resource.end = extslotaddr + devsize - 1; + } else { + printk(KERN_ERR "%s: Cannot provide slot space " + "(%dMiB required, up to %dMiB supported)\n", + tdev->dev.bus_id, devsize >> 20, + max(slotsize, extslotsize) >> 20); + kfree(tdev); + goto out_err; } + tdev->resource.name = tdev->name; + tdev->resource.flags = IORESOURCE_MEM; + + tc_device_get_irq(tdev); + device_register(&tdev->dev); + list_add_tail(&tdev->node, &tbus->devices); + +out_err: iounmap(module); } } /* - * the main entry + * The main entry. */ static int __init tc_init(void) { - int tc_clock; - int i; - unsigned long slot0addr; - unsigned long slot_size; - - if (!TURBOCHANNEL) + /* Initialize the TURBOchannel bus */ + if (tc_bus_get_info(&tc_bus)) return 0; - for (i = 0; i < MAX_SLOT; i++) { - tc_bus[i].base_addr = 0; - tc_bus[i].name[0] = 0; - tc_bus[i].vendor[0] = 0; - tc_bus[i].firmware[0] = 0; - tc_bus[i].interrupt = -1; - tc_bus[i].flags = FREE; - } - - info = rex_gettcinfo(); - slot0addr = CPHYSADDR((long)rex_slot_address(0)); - - switch (mips_machtype) { - case MACH_DS5000_200: - num_tcslots = 7; - break; - case MACH_DS5000_1XX: - case MACH_DS5000_2X0: - case MACH_DS5900: - num_tcslots = 3; - break; - case MACH_DS5000_XX: - default: - num_tcslots = 2; - break; - } - - tc_clock = 10000 / info->clk_period; - - if (info->slot_size && slot0addr) { - pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n", - info->revision, tc_clock / 10, tc_clock % 10, - info->parity ? "" : "out"); - - slot_size = info->slot_size << 20; - - tc_probe(slot0addr, slot_size, num_tcslots); - - for (i = 0; i < num_tcslots; i++) { - if (!tc_bus[i].base_addr) - continue; - pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor, - tc_bus[i].name, tc_bus[i].firmware); + INIT_LIST_HEAD(&tc_bus.devices); + strcpy(tc_bus.dev.bus_id, "tc"); + device_register(&tc_bus.dev); + + if (tc_bus.info.slot_size) { + unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; + + pr_info("tc: TURBOchannel rev. %d at %d.%d MHz " + "(with%s parity)\n", tc_bus.info.revision, + tc_clock / 10, tc_clock % 10, + tc_bus.info.parity ? "" : "out"); + + tc_bus.resource[0].start = tc_bus.slot_base; + tc_bus.resource[0].end = tc_bus.slot_base + + (tc_bus.info.slot_size << 20) * + tc_bus.num_tcslots; + tc_bus.resource[0].name = tc_bus.name; + tc_bus.resource[0].flags = IORESOURCE_MEM; + if (request_resource(&iomem_resource, + &tc_bus.resource[0]) < 0) { + printk(KERN_ERR "tc: Cannot reserve resource\n"); + return 0; + } + if (tc_bus.ext_slot_size) { + tc_bus.resource[1].start = tc_bus.ext_slot_base; + tc_bus.resource[1].end = tc_bus.ext_slot_base + + tc_bus.ext_slot_size * + tc_bus.num_tcslots; + tc_bus.resource[1].name = tc_bus.name; + tc_bus.resource[1].flags = IORESOURCE_MEM; + if (request_resource(&iomem_resource, + &tc_bus.resource[1]) < 0) { + printk(KERN_ERR + "tc: Cannot reserve resource\n"); + release_resource(&tc_bus.resource[0]); + return 0; + } } + + tc_bus_add_devices(&tc_bus); } return 0; } subsys_initcall(tc_init); - -EXPORT_SYMBOL(search_tc_card); -EXPORT_SYMBOL(claim_tc_card); -EXPORT_SYMBOL(release_tc_card); -EXPORT_SYMBOL(get_tc_base_addr); -EXPORT_SYMBOL(get_tc_irq_nr); -EXPORT_SYMBOL(get_tc_speed); diff --git a/trunk/drivers/usb/host/ehci-ps3.c b/trunk/drivers/usb/host/ehci-ps3.c index 4d781a2a9807..371f194a9d39 100644 --- a/trunk/drivers/usb/host/ehci-ps3.c +++ b/trunk/drivers/usb/host/ehci-ps3.c @@ -104,7 +104,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 46fa57a520d0..ec0da0343be4 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -677,10 +677,10 @@ static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO return ehci_big_endian_mmio(ehci) ? - readl_be(regs) : - readl(regs); + readl_be((__force u32 *)regs) : + readl((__force u32 *)regs); #else - return readl(regs); + return readl((__force u32 *)regs); #endif } @@ -689,10 +689,10 @@ static inline void ehci_writel (const struct ehci_hcd *ehci, { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci_big_endian_mmio(ehci) ? - writel_be(val, regs) : - writel(val, regs); + writel_be(val, (__force u32 *)regs) : + writel(val, (__force u32 *)regs); #else - writel(val, regs); + writel(val, (__force u32 *)regs); #endif } diff --git a/trunk/drivers/usb/host/ohci-ps3.c b/trunk/drivers/usb/host/ohci-ps3.c index 62283a3926de..69d948b4a701 100644 --- a/trunk/drivers/usb/host/ohci-ps3.c +++ b/trunk/drivers/usb/host/ohci-ps3.c @@ -107,7 +107,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", diff --git a/trunk/drivers/usb/host/ohci.h b/trunk/drivers/usb/host/ohci.h index c2b5ecfe5e9f..0dafcda37291 100644 --- a/trunk/drivers/usb/host/ohci.h +++ b/trunk/drivers/usb/host/ohci.h @@ -507,10 +507,10 @@ static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO return big_endian_mmio(ohci) ? - readl_be (regs) : - readl (regs); + readl_be ((__force u32 *)regs) : + readl ((__force u32 *)regs); #else - return readl (regs); + return readl ((__force u32 *)regs); #endif } @@ -519,10 +519,10 @@ static inline void _ohci_writel (const struct ohci_hcd *ohci, { #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO big_endian_mmio(ohci) ? - writel_be (val, regs) : - writel (val, regs); + writel_be (val, (__force u32 *)regs) : + writel (val, (__force u32 *)regs); #else - writel (val, regs); + writel (val, (__force u32 *)regs); #endif } diff --git a/trunk/drivers/usb/net/gl620a.c b/trunk/drivers/usb/net/gl620a.c index 31e5fe363fdc..a6f0f4d934df 100644 --- a/trunk/drivers/usb/net/gl620a.c +++ b/trunk/drivers/usb/net/gl620a.c @@ -70,12 +70,12 @@ (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) struct gl_packet { - __le32 packet_length; + u32 packet_length; char packet_data [1]; }; struct gl_header { - __le32 packet_count; + u32 packet_count; struct gl_packet packets; }; @@ -85,14 +85,15 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) struct gl_packet *packet; struct sk_buff *gl_skb; u32 size; - u32 count; header = (struct gl_header *) skb->data; // get the packet count of the received skb - count = le32_to_cpu(header->packet_count); - if (count > GL_MAX_TRANSMIT_PACKETS) { - dbg("genelink: invalid received packet count %u", count); + le32_to_cpus(&header->packet_count); + if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS) + || (header->packet_count < 0)) { + dbg("genelink: invalid received packet count %d", + header->packet_count); return 0; } @@ -102,7 +103,7 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) // decrement the length for the packet count size 4 bytes skb_pull(skb, 4); - while (count > 1) { + while (header->packet_count > 1) { // get the packet length size = le32_to_cpu(packet->packet_length); @@ -123,8 +124,9 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } // advance to the next packet - packet = (struct gl_packet *)&packet->packet_data[size]; - count--; + packet = (struct gl_packet *) + &packet->packet_data [size]; + header->packet_count--; // shift the data pointer to the next gl_packet skb_pull(skb, size + 4); @@ -147,8 +149,8 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) int length = skb->len; int headroom = skb_headroom(skb); int tailroom = skb_tailroom(skb); - __le32 *packet_count; - __le32 *packet_len; + u32 *packet_count; + u32 *packet_len; // FIXME: magic numbers, bleech padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; @@ -170,7 +172,7 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) } // attach the packet count to the header - packet_count = (__le32 *) skb_push(skb, (4 + 4*1)); + packet_count = (u32 *) skb_push(skb, (4 + 4*1)); packet_len = packet_count + 1; *packet_count = cpu_to_le32(1); diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 3ec24870bca9..06b4fffc189c 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -170,13 +170,13 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - __le32 *buf; + u32 *buf; int result, i, length; /* Number of integers required to contain the array */ length = (((size - 1) | 3) + 1)/4; - buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); + buf = kcalloc(length, sizeof(u32), GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); return -ENOMEM; @@ -216,13 +216,13 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - __le32 *buf; + u32 *buf; int result, i, length; /* Number of integers required to contain the array */ length = (((size - 1) | 3) + 1)/4; - buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); + buf = kmalloc(length * sizeof(u32), GFP_KERNEL); if (!buf) { dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); diff --git a/trunk/fs/dlm/lowcomms-tcp.c b/trunk/fs/dlm/lowcomms-tcp.c index 07e0a122c32f..f1efd17b2614 100644 --- a/trunk/fs/dlm/lowcomms-tcp.c +++ b/trunk/fs/dlm/lowcomms-tcp.c @@ -268,12 +268,12 @@ static void close_connection(struct connection *con, bool and_other) static int receive_from_sock(struct connection *con) { int ret = 0; - struct msghdr msg = {}; - struct kvec iov[2]; + struct msghdr msg; + struct iovec iov[2]; + mm_segment_t fs; unsigned len; int r; int call_again_soon = 0; - int nvec; mutex_lock(&con->sock_mutex); @@ -293,13 +293,21 @@ static int receive_from_sock(struct connection *con) cbuf_init(&con->cb, PAGE_CACHE_SIZE); } + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = iov; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_flags = 0; + /* * iov[0] is the bit of the circular buffer between the current end * point (cb.base + cb.len) and the end of the buffer. */ iov[0].iov_len = con->cb.base - cbuf_data(&con->cb); iov[0].iov_base = page_address(con->rx_page) + cbuf_data(&con->cb); - nvec = 1; + iov[1].iov_len = 0; /* * iov[1] is the bit of the circular buffer between the start of the @@ -309,12 +317,15 @@ static int receive_from_sock(struct connection *con) iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&con->cb); iov[1].iov_len = con->cb.base; iov[1].iov_base = page_address(con->rx_page); - nvec = 2; + msg.msg_iovlen = 2; } len = iov[0].iov_len + iov[1].iov_len; - r = ret = kernel_recvmsg(con->sock, &msg, iov, nvec, len, + fs = get_fs(); + set_fs(get_ds()); + r = ret = sock_recvmsg(con->sock, &msg, len, MSG_DONTWAIT | MSG_NOSIGNAL); + set_fs(fs); if (ret <= 0) goto out_close; diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index a86a55ccf874..7196f50fe152 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -828,7 +828,9 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) mutex_unlock(&crypt_stat->cs_tfm_mutex); goto out; } - crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY); + crypto_blkcipher_set_flags(crypt_stat->tfm, + (ECRYPTFS_DEFAULT_CHAINING_MODE + | CRYPTO_TFM_REQ_WEAK_KEY)); mutex_unlock(&crypt_stat->cs_tfm_mutex); rc = 0; out: diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index 0f897109759b..afb64bdbe6ad 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -176,6 +176,7 @@ ecryptfs_get_key_payload_data(struct key *key) #define ECRYPTFS_FILE_SIZE_BYTES 8 #define ECRYPTFS_DEFAULT_CIPHER "aes" #define ECRYPTFS_DEFAULT_KEY_BYTES 16 +#define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC #define ECRYPTFS_DEFAULT_HASH "md5" #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED diff --git a/trunk/include/asm-alpha/io.h b/trunk/include/asm-alpha/io.h index 24bdcc8b63aa..5d15af24573b 100644 --- a/trunk/include/asm-alpha/io.h +++ b/trunk/include/asm-alpha/io.h @@ -524,6 +524,15 @@ extern void outsb (unsigned long port, const void *src, unsigned long count); extern void outsw (unsigned long port, const void *src, unsigned long count); extern void outsl (unsigned long port, const void *src, unsigned long count); +/* + * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. Presently + * only used by some shared memory 8390 Ethernet cards anyway. + */ + +#define eth_io_copy_and_sum(skb,src,len,unused) \ + memcpy_fromio((skb)->data,src,len) + /* * The Alpha Jensen hardware for some rather strange reason puts * the RTC clock at 0x170 instead of 0x70. Probably due to some diff --git a/trunk/include/asm-arm/arch-ixp4xx/io.h b/trunk/include/asm-arm/arch-ixp4xx/io.h index b7b5414d9320..0d517267fb63 100644 --- a/trunk/include/asm-arm/arch-ixp4xx/io.h +++ b/trunk/include/asm-arm/arch-ixp4xx/io.h @@ -238,6 +238,9 @@ __ixp4xx_readsl(const volatile void __iomem *bus_addr, u32 *vaddr, u32 count) #define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l)) #define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l)) +#define eth_io_copy_and_sum(s,c,l,b) \ + eth_copy_and_sum((s),__mem_pci(c),(l),(b)) + static inline int check_signature(const unsigned char __iomem *bus_addr, const unsigned char *signature, int length) diff --git a/trunk/include/asm-arm/io.h b/trunk/include/asm-arm/io.h index 5f60b4220906..288f76b166d0 100644 --- a/trunk/include/asm-arm/io.h +++ b/trunk/include/asm-arm/io.h @@ -182,6 +182,9 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) #define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) +#define eth_io_copy_and_sum(s,c,l,b) \ + eth_copy_and_sum((s),__mem_pci(c),(l),(b)) + #elif !defined(readb) #define readb(c) (__readwrite_bug("readb"),0) @@ -191,6 +194,8 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writew(v,c) __readwrite_bug("writew") #define writel(v,c) __readwrite_bug("writel") +#define eth_io_copy_and_sum(s,c,l,b) __readwrite_bug("eth_io_copy_and_sum") + #define check_signature(io,sig,len) (0) #endif /* __mem_pci */ diff --git a/trunk/include/asm-avr32/arch-at32ap/at32ap7000.h b/trunk/include/asm-avr32/arch-at32ap/at32ap7000.h index 3914d7b94ff4..ba85e04553d4 100644 --- a/trunk/include/asm-avr32/arch-at32ap/at32ap7000.h +++ b/trunk/include/asm-avr32/arch-at32ap/at32ap7000.h @@ -24,12 +24,10 @@ #define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32) #define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32) #define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32) -#define GPIO_PIOE_BASE (GPIO_PIOD_BASE + 32) #define GPIO_PIN_PA(N) (GPIO_PIOA_BASE + (N)) #define GPIO_PIN_PB(N) (GPIO_PIOB_BASE + (N)) #define GPIO_PIN_PC(N) (GPIO_PIOC_BASE + (N)) #define GPIO_PIN_PD(N) (GPIO_PIOD_BASE + (N)) -#define GPIO_PIN_PE(N) (GPIO_PIOE_BASE + (N)) #endif /* __ASM_ARCH_AT32AP7000_H__ */ diff --git a/trunk/include/asm-avr32/arch-at32ap/gpio.h b/trunk/include/asm-avr32/arch-at32ap/gpio.h deleted file mode 100644 index fcb756bdaa8e..000000000000 --- a/trunk/include/asm-avr32/arch-at32ap/gpio.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __ASM_AVR32_ARCH_GPIO_H -#define __ASM_AVR32_ARCH_GPIO_H - -#include -#include - - -/* Arch-neutral GPIO API */ -int __must_check gpio_request(unsigned int gpio, const char *label); -void gpio_free(unsigned int gpio); - -int gpio_direction_input(unsigned int gpio); -int gpio_direction_output(unsigned int gpio); -int gpio_get_value(unsigned int gpio); -void gpio_set_value(unsigned int gpio, int value); - -static inline int gpio_to_irq(unsigned int gpio) -{ - return gpio + GPIO_IRQ_BASE; -} - -static inline int irq_to_gpio(unsigned int irq) -{ - return irq - GPIO_IRQ_BASE; -} - -#endif /* __ASM_AVR32_ARCH_GPIO_H */ diff --git a/trunk/include/asm-avr32/arch-at32ap/irq.h b/trunk/include/asm-avr32/arch-at32ap/irq.h deleted file mode 100644 index 5adffab9a577..000000000000 --- a/trunk/include/asm-avr32/arch-at32ap/irq.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ASM_AVR32_ARCH_IRQ_H -#define __ASM_AVR32_ARCH_IRQ_H - -#define EIM_IRQ_BASE NR_INTERNAL_IRQS -#define NR_EIM_IRQS 32 - -#define AT32_EXTINT(n) (EIM_IRQ_BASE + (n)) - -#define GPIO_IRQ_BASE (EIM_IRQ_BASE + NR_EIM_IRQS) -#define NR_GPIO_IRQS (5 * 32) - -#define NR_IRQS (GPIO_IRQ_BASE + NR_GPIO_IRQS) - -#endif /* __ASM_AVR32_ARCH_IRQ_H */ diff --git a/trunk/include/asm-avr32/arch-at32ap/portmux.h b/trunk/include/asm-avr32/arch-at32ap/portmux.h index 9930871decde..83c690571322 100644 --- a/trunk/include/asm-avr32/arch-at32ap/portmux.h +++ b/trunk/include/asm-avr32/arch-at32ap/portmux.h @@ -15,14 +15,12 @@ * * The following flags determine the initial state of the pin. */ -#define AT32_GPIOF_PULLUP 0x00000001 /* (not-OUT) Enable pull-up */ -#define AT32_GPIOF_OUTPUT 0x00000002 /* (OUT) Enable output driver */ -#define AT32_GPIOF_HIGH 0x00000004 /* (OUT) Set output high */ -#define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */ +#define AT32_GPIOF_PULLUP 0x00000001 /* Enable pull-up */ +#define AT32_GPIOF_OUTPUT 0x00000002 /* Enable output driver */ +#define AT32_GPIOF_HIGH 0x00000004 /* Set output high */ void at32_select_periph(unsigned int pin, unsigned int periph, unsigned long flags); void at32_select_gpio(unsigned int pin, unsigned long flags); -void at32_reserve_pin(unsigned int pin); #endif /* __ASM_ARCH_PORTMUX_H__ */ diff --git a/trunk/include/asm-avr32/checksum.h b/trunk/include/asm-avr32/checksum.h index 4ddbfd2486af..af9d53f0f5d2 100644 --- a/trunk/include/asm-avr32/checksum.h +++ b/trunk/include/asm-avr32/checksum.h @@ -38,7 +38,7 @@ __wsum csum_partial_copy_generic(const void *src, void *dst, int len, * passed in an incorrect kernel address to one of these functions. * * If you use these functions directly please don't forget the - * access_ok(). + * verify_area(). */ static inline __wsum csum_partial_copy_nocheck(const void *src, void *dst, diff --git a/trunk/include/asm-avr32/dma-mapping.h b/trunk/include/asm-avr32/dma-mapping.h index 115813e48fe0..5c01e27f0b41 100644 --- a/trunk/include/asm-avr32/dma-mapping.h +++ b/trunk/include/asm-avr32/dma-mapping.h @@ -32,14 +32,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -/* - * dma_map_single can't fail as it is implemented now. - */ -static inline int dma_mapping_error(dma_addr_t addr) -{ - return 0; -} - /** * dma_alloc_coherent - allocate consistent memory for DMA * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices diff --git a/trunk/include/asm-avr32/gpio.h b/trunk/include/asm-avr32/gpio.h deleted file mode 100644 index 19e8ccc77db3..000000000000 --- a/trunk/include/asm-avr32/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_GPIO_H -#define __ASM_AVR32_GPIO_H - -#include - -#endif /* __ASM_AVR32_GPIO_H */ diff --git a/trunk/include/asm-avr32/irq.h b/trunk/include/asm-avr32/irq.h index 83e6549d7783..f7e725707dd7 100644 --- a/trunk/include/asm-avr32/irq.h +++ b/trunk/include/asm-avr32/irq.h @@ -2,12 +2,8 @@ #define __ASM_AVR32_IRQ_H #define NR_INTERNAL_IRQS 64 - -#include - -#ifndef NR_IRQS -#define NR_IRQS (NR_INTERNAL_IRQS) -#endif +#define NR_EXTERNAL_IRQS 64 +#define NR_IRQS (NR_INTERNAL_IRQS + NR_EXTERNAL_IRQS) #define irq_canonicalize(i) (i) diff --git a/trunk/include/asm-avr32/posix_types.h b/trunk/include/asm-avr32/posix_types.h index 9e255b999639..2831b039b349 100644 --- a/trunk/include/asm-avr32/posix_types.h +++ b/trunk/include/asm-avr32/posix_types.h @@ -23,7 +23,7 @@ typedef unsigned short __kernel_ipc_pid_t; typedef unsigned int __kernel_uid_t; typedef unsigned int __kernel_gid_t; typedef unsigned long __kernel_size_t; -typedef long __kernel_ssize_t; +typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; diff --git a/trunk/include/asm-avr32/uaccess.h b/trunk/include/asm-avr32/uaccess.h index 74a679e9098c..821deb5a9d28 100644 --- a/trunk/include/asm-avr32/uaccess.h +++ b/trunk/include/asm-avr32/uaccess.h @@ -68,6 +68,12 @@ static inline void set_fs(mm_segment_t s) #define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0)) +static inline int +verify_area(int type, const void __user *addr, unsigned long size) +{ + return access_ok(type, addr, size) ? 0 : -EFAULT; +} + /* Generic arbitrary sized copy. Return the number of bytes NOT copied */ extern __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); diff --git a/trunk/include/asm-cris/io.h b/trunk/include/asm-cris/io.h index d196dd6b2df3..716c69bc58f8 100644 --- a/trunk/include/asm-cris/io.h +++ b/trunk/include/asm-cris/io.h @@ -121,6 +121,11 @@ static inline void writel(unsigned int b, volatile void __iomem *addr) #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +/* + * Again, CRIS does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(b),(c),(d)) /* The following is junk needed for the arch-independent code but which * we never use in the CRIS port diff --git a/trunk/include/asm-i386/io.h b/trunk/include/asm-i386/io.h index 59fe616933c4..86ff5e83be2f 100644 --- a/trunk/include/asm-i386/io.h +++ b/trunk/include/asm-i386/io.h @@ -218,6 +218,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int */ #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET)) +/* + * Again, i386 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(b),(c),(d)) + /* * Cache management * diff --git a/trunk/include/asm-mips/dec/tc.h b/trunk/include/asm-mips/dec/tc.h deleted file mode 100644 index 9cb51f24d42c..000000000000 --- a/trunk/include/asm-mips/dec/tc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Interface to the TURBOchannel related routines - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (c) 1998 Harald Koerfgen - */ -#ifndef __ASM_DEC_TC_H -#define __ASM_DEC_TC_H - -/* - * Search for a TURBOchannel Option Module - * with a certain name. Returns slot number - * of the first card not in use or -ENODEV - * if none found. - */ -extern int search_tc_card(const char *); -/* - * Marks the card in slot as used - */ -extern void claim_tc_card(int); -/* - * Marks the card in slot as free - */ -extern void release_tc_card(int); -/* - * Return base address of card in slot - */ -extern unsigned long get_tc_base_addr(int); -/* - * Return interrupt number of slot - */ -extern unsigned long get_tc_irq_nr(int); -/* - * Return TURBOchannel clock frequency in Hz - */ -extern unsigned long get_tc_speed(void); - -#endif /* __ASM_DEC_TC_H */ diff --git a/trunk/include/asm-mips/dec/tcinfo.h b/trunk/include/asm-mips/dec/tcinfo.h deleted file mode 100644 index cc23509ee77a..000000000000 --- a/trunk/include/asm-mips/dec/tcinfo.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Various TURBOchannel related stuff - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Information obtained through the get_tcinfo prom call - * created from: - * - * TURBOchannel Firmware Specification - * - * EK-TCAAD-FS-004 - * from Digital Equipment Corporation - * - * Copyright (c) 1998 Harald Koerfgen - */ - -typedef struct { - int revision; - int clk_period; - int slot_size; - int io_timeout; - int dma_range; - int max_dma_burst; - int parity; - int reserved[4]; -} tcinfo; - -#define MAX_SLOT 7 - -typedef struct { - unsigned long base_addr; - unsigned char name[9]; - unsigned char vendor[9]; - unsigned char firmware[9]; - int interrupt; - int flags; -} slot_info; - -/* - * Values for flags - */ -#define FREE 1<<0 -#define IN_USE 1<<1 - - diff --git a/trunk/include/asm-mips/dec/tcmodule.h b/trunk/include/asm-mips/dec/tcmodule.h deleted file mode 100644 index 6268e8915d87..000000000000 --- a/trunk/include/asm-mips/dec/tcmodule.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Offsets for the ROM header locations for - * TURBOchannel cards - * - * created from: - * - * TURBOchannel Firmware Specification - * - * EK-TCAAD-FS-004 - * from Digital Equipment Corporation - * - * Jan.1998 Harald Koerfgen - */ -#ifndef __ASM_DEC_TCMODULE_H -#define __ASM_DEC_TCMODULE_H - -#define OLDCARD 0x3c0000 -#define NEWCARD 0x000000 - -#define TC_ROM_WIDTH 0x3e0 -#define TC_ROM_STRIDE 0x3e4 -#define TC_ROM_SIZE 0x3e8 -#define TC_SLOT_SIZE 0x3ec -#define TC_PATTERN0 0x3f0 -#define TC_PATTERN1 0x3f4 -#define TC_PATTERN2 0x3f8 -#define TC_PATTERN3 0x3fc -#define TC_FIRM_VER 0x400 -#define TC_VENDOR 0x420 -#define TC_MODULE 0x440 -#define TC_FIRM_TYPE 0x460 -#define TC_FLAGS 0x470 -#define TC_ROM_OBJECTS 0x480 - -#endif /* __ASM_DEC_TCMODULE_H */ diff --git a/trunk/include/asm-mips/io.h b/trunk/include/asm-mips/io.h index b6a2eb816628..67f081078904 100644 --- a/trunk/include/asm-mips/io.h +++ b/trunk/include/asm-mips/io.h @@ -555,6 +555,12 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *); */ #define __ISA_IO_base ((char *)(isa_slot_offset)) +/* + * We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. + */ +#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) + /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that diff --git a/trunk/include/asm-parisc/io.h b/trunk/include/asm-parisc/io.h index ca46e7cc0940..c1963ce19dd2 100644 --- a/trunk/include/asm-parisc/io.h +++ b/trunk/include/asm-parisc/io.h @@ -191,6 +191,15 @@ void memset_io(volatile void __iomem *addr, unsigned char val, int count); void memcpy_fromio(void *dst, const volatile void __iomem *src, int count); void memcpy_toio(volatile void __iomem *dst, const void *src, int count); +/* + * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and + * just copy it. The net code will then do the checksum later. Presently + * only used by some shared memory 8390 Ethernet cards anyway. + */ + +#define eth_io_copy_and_sum(skb,src,len,unused) \ + memcpy_fromio((skb)->data,(src),(len)) + /* Port-space IO */ #define inb_p inb diff --git a/trunk/include/asm-ppc/io.h b/trunk/include/asm-ppc/io.h index 95d590423cf2..ccf1a9bb2e43 100644 --- a/trunk/include/asm-ppc/io.h +++ b/trunk/include/asm-ppc/io.h @@ -358,6 +358,8 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int } #endif +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void __force *)(void __iomem *)(b),(c),(d)) + /* * Map in an area of physical address space, for accessing * I/O devices etc. diff --git a/trunk/include/asm-x86_64/io.h b/trunk/include/asm-x86_64/io.h index f5d84bb7c948..6ee9fadaaacb 100644 --- a/trunk/include/asm-x86_64/io.h +++ b/trunk/include/asm-x86_64/io.h @@ -248,6 +248,12 @@ void memset_io(volatile void __iomem *a, int b, size_t c); */ #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET)) +/* + * Again, x86-64 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d)) + /* Nothing to do */ #define dma_cache_inv(_start,_size) do { } while (0) diff --git a/trunk/include/crypto/algapi.h b/trunk/include/crypto/algapi.h index 4e05e93ff681..5748aecdb414 100644 --- a/trunk/include/crypto/algapi.h +++ b/trunk/include/crypto/algapi.h @@ -18,8 +18,8 @@ struct module; struct seq_file; struct crypto_type { - unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask); - int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); + unsigned int (*ctxsize)(struct crypto_alg *alg); + int (*init)(struct crypto_tfm *tfm); void (*exit)(struct crypto_tfm *tfm); void (*show)(struct seq_file *m, struct crypto_alg *alg); }; @@ -93,8 +93,7 @@ struct crypto_template *crypto_lookup_template(const char *name); int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg, struct crypto_instance *inst); void crypto_drop_spawn(struct crypto_spawn *spawn); -struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, - u32 mask); +struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn); struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, u32 type, u32 mask); @@ -133,28 +132,11 @@ static inline void *crypto_blkcipher_ctx_aligned(struct crypto_blkcipher *tfm) return crypto_tfm_ctx_aligned(&tfm->base); } -static inline struct crypto_cipher *crypto_spawn_cipher( - struct crypto_spawn *spawn) -{ - u32 type = CRYPTO_ALG_TYPE_CIPHER; - u32 mask = CRYPTO_ALG_TYPE_MASK; - - return __crypto_cipher_cast(crypto_spawn_tfm(spawn, type, mask)); -} - static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm) { return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher; } -static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn) -{ - u32 type = CRYPTO_ALG_TYPE_HASH; - u32 mask = CRYPTO_ALG_TYPE_HASH_MASK; - - return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask)); -} - static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm) { return crypto_tfm_ctx_aligned(&tfm->base); diff --git a/trunk/include/linux/atmarp.h b/trunk/include/linux/atmarp.h index 231f4bdec730..ee108f9e9cb7 100644 --- a/trunk/include/linux/atmarp.h +++ b/trunk/include/linux/atmarp.h @@ -6,7 +6,9 @@ #ifndef _LINUX_ATMARP_H #define _LINUX_ATMARP_H +#ifdef __KERNEL__ #include +#endif #include #include diff --git a/trunk/include/linux/crypto.h b/trunk/include/linux/crypto.h index 779aa78ee643..4aa9046601da 100644 --- a/trunk/include/linux/crypto.h +++ b/trunk/include/linux/crypto.h @@ -51,9 +51,15 @@ /* * Transform masks and values (for crt_flags). */ +#define CRYPTO_TFM_MODE_MASK 0x000000ff #define CRYPTO_TFM_REQ_MASK 0x000fff00 #define CRYPTO_TFM_RES_MASK 0xfff00000 +#define CRYPTO_TFM_MODE_ECB 0x00000001 +#define CRYPTO_TFM_MODE_CBC 0x00000002 +#define CRYPTO_TFM_MODE_CFB 0x00000004 +#define CRYPTO_TFM_MODE_CTR 0x00000008 + #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 #define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200 #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 @@ -65,8 +71,12 @@ /* * Miscellaneous stuff. */ +#define CRYPTO_UNSPEC 0 #define CRYPTO_MAX_ALG_NAME 64 +#define CRYPTO_DIR_ENCRYPT 1 +#define CRYPTO_DIR_DECRYPT 0 + /* * The macro CRYPTO_MINALIGN_ATTR (along with the void * type in the actual * declaration) is used to ensure that the crypto_tfm context structure is @@ -138,6 +148,19 @@ struct cipher_alg { unsigned int keylen); void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src); + + unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) __deprecated; + unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) __deprecated; + unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) __deprecated; + unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) __deprecated; }; struct digest_alg { @@ -220,6 +243,11 @@ int crypto_unregister_alg(struct crypto_alg *alg); #ifdef CONFIG_CRYPTO int crypto_has_alg(const char *name, u32 type, u32 mask); #else +static inline int crypto_alg_available(const char *name, u32 flags) +{ + return 0; +} + static inline int crypto_has_alg(const char *name, u32 type, u32 mask) { return 0; @@ -311,15 +339,10 @@ struct crypto_tfm { void *__crt_ctx[] CRYPTO_MINALIGN_ATTR; }; -struct crypto_blkcipher { - struct crypto_tfm base; -}; - -struct crypto_cipher { - struct crypto_tfm base; -}; +#define crypto_cipher crypto_tfm +#define crypto_comp crypto_tfm -struct crypto_comp { +struct crypto_blkcipher { struct crypto_tfm base; }; @@ -372,11 +395,40 @@ static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm) return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK; } +static unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) + __deprecated; +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_min_keysize; +} + +static unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) + __deprecated; +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->__crt_alg->cra_cipher.cia_max_keysize; +} + +static unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) __deprecated; +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_ivsize; +} + static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm) { return tfm->__crt_alg->cra_blocksize; } +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); + return tfm->__crt_alg->cra_digest.dia_digestsize; +} + static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm) { return tfm->__crt_alg->cra_alignmask; @@ -581,7 +633,7 @@ static inline struct crypto_cipher *crypto_alloc_cipher(const char *alg_name, static inline struct crypto_tfm *crypto_cipher_tfm(struct crypto_cipher *tfm) { - return &tfm->base; + return tfm; } static inline void crypto_free_cipher(struct crypto_cipher *tfm) @@ -757,6 +809,76 @@ static inline int crypto_hash_setkey(struct crypto_hash *hash, return crypto_hash_crt(hash)->setkey(hash, key, keylen); } +static int crypto_cipher_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) __deprecated; +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); +} + +static int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) __deprecated; +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv); +} + +static int crypto_cipher_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) __deprecated; +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); +} + +static int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) __deprecated; +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv); +} + +static void crypto_cipher_set_iv(struct crypto_tfm *tfm, + const u8 *src, unsigned int len) __deprecated; +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, + const u8 *src, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(tfm->crt_cipher.cit_iv, src, len); +} + +static void crypto_cipher_get_iv(struct crypto_tfm *tfm, + u8 *dst, unsigned int len) __deprecated; +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, + u8 *dst, unsigned int len) +{ + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); + memcpy(dst, tfm->crt_cipher.cit_iv, len); +} + static inline struct crypto_comp *__crypto_comp_cast(struct crypto_tfm *tfm) { return (struct crypto_comp *)tfm; @@ -781,7 +903,7 @@ static inline struct crypto_comp *crypto_alloc_comp(const char *alg_name, static inline struct crypto_tfm *crypto_comp_tfm(struct crypto_comp *tfm) { - return &tfm->base; + return tfm; } static inline void crypto_free_comp(struct crypto_comp *tfm) @@ -812,16 +934,14 @@ static inline int crypto_comp_compress(struct crypto_comp *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { - return crypto_comp_crt(tfm)->cot_compress(crypto_comp_tfm(tfm), - src, slen, dst, dlen); + return crypto_comp_crt(tfm)->cot_compress(tfm, src, slen, dst, dlen); } static inline int crypto_comp_decompress(struct crypto_comp *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { - return crypto_comp_crt(tfm)->cot_decompress(crypto_comp_tfm(tfm), - src, slen, dst, dlen); + return crypto_comp_crt(tfm)->cot_decompress(tfm, src, slen, dst, dlen); } #endif /* _LINUX_CRYPTO_H */ diff --git a/trunk/include/linux/gfp.h b/trunk/include/linux/gfp.h index 063799ea6be0..00c314aedab7 100644 --- a/trunk/include/linux/gfp.h +++ b/trunk/include/linux/gfp.h @@ -70,7 +70,7 @@ struct vm_area_struct; #ifdef CONFIG_NUMA #define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) #else -#define GFP_THISNODE ((__force gfp_t)0) +#define GFP_THISNODE 0 #endif diff --git a/trunk/include/linux/i2c-id.h b/trunk/include/linux/i2c-id.h index 6e7ec4c76178..d38778f2fbec 100644 --- a/trunk/include/linux/i2c-id.h +++ b/trunk/include/linux/i2c-id.h @@ -115,8 +115,6 @@ #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ #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_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ diff --git a/trunk/include/linux/if_packet.h b/trunk/include/linux/if_packet.h index f3de05c30678..99393ef3af39 100644 --- a/trunk/include/linux/if_packet.h +++ b/trunk/include/linux/if_packet.h @@ -41,7 +41,6 @@ struct sockaddr_ll #define PACKET_RX_RING 5 #define PACKET_STATISTICS 6 #define PACKET_COPY_THRESH 7 -#define PACKET_AUXDATA 8 struct tpacket_stats { @@ -49,15 +48,6 @@ struct tpacket_stats unsigned int tp_drops; }; -struct tpacket_auxdata -{ - __u32 tp_status; - __u32 tp_len; - __u32 tp_snaplen; - __u16 tp_mac; - __u16 tp_net; -}; - struct tpacket_hdr { unsigned long tp_status; diff --git a/trunk/include/linux/net.h b/trunk/include/linux/net.h index 4db21e63d8d2..f28d8a2e2c91 100644 --- a/trunk/include/linux/net.h +++ b/trunk/include/linux/net.h @@ -24,7 +24,7 @@ struct poll_table_struct; struct inode; -#define NPROTO 33 /* should be enough for now.. */ +#define NPROTO 32 /* should be enough for now.. */ #define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 1a528548cd1d..2e37f5012788 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -589,7 +589,7 @@ extern int dev_open(struct net_device *dev); extern int dev_close(struct net_device *dev); extern int dev_queue_xmit(struct sk_buff *skb); extern int register_netdevice(struct net_device *dev); -extern void unregister_netdevice(struct net_device *dev); +extern int unregister_netdevice(struct net_device *dev); extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); diff --git a/trunk/include/linux/netfilter/Kbuild b/trunk/include/linux/netfilter/Kbuild index 43397a414cd6..6328175a1c3a 100644 --- a/trunk/include/linux/netfilter/Kbuild +++ b/trunk/include/linux/netfilter/Kbuild @@ -33,7 +33,6 @@ header-y += xt_tcpmss.h header-y += xt_tcpudp.h header-y += xt_SECMARK.h header-y += xt_CONNSECMARK.h -header-y += xt_TCPMSS.h unifdef-y += nf_conntrack_common.h unifdef-y += nf_conntrack_ftp.h diff --git a/trunk/include/linux/netfilter/nf_conntrack_sane.h b/trunk/include/linux/netfilter/nf_conntrack_sane.h deleted file mode 100644 index 4767d6e23e97..000000000000 --- a/trunk/include/linux/netfilter/nf_conntrack_sane.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _NF_CONNTRACK_SANE_H -#define _NF_CONNTRACK_SANE_H -/* SANE tracking. */ - -#ifdef __KERNEL__ - -#define SANE_PORT 6566 - -enum sane_state { - SANE_STATE_NORMAL, - SANE_STATE_START_REQUESTED, -}; - -/* This structure exists only once per master */ -struct nf_ct_sane_master { - enum sane_state state; -}; - -#endif /* __KERNEL__ */ - -#endif /* _NF_CONNTRACK_SANE_H */ diff --git a/trunk/include/linux/netfilter/nf_conntrack_tcp.h b/trunk/include/linux/netfilter/nf_conntrack_tcp.h index 007af4c2770b..2f4e98b90cc0 100644 --- a/trunk/include/linux/netfilter/nf_conntrack_tcp.h +++ b/trunk/include/linux/netfilter/nf_conntrack_tcp.h @@ -27,9 +27,6 @@ enum tcp_conntrack { /* This sender sent FIN first */ #define IP_CT_TCP_FLAG_CLOSE_INIT 0x04 -/* Be liberal in window checking */ -#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08 - #ifdef __KERNEL__ struct ip_ct_tcp_state { @@ -37,6 +34,7 @@ struct ip_ct_tcp_state { u_int32_t td_maxend; /* max of ack + max(win, 1) */ u_int32_t td_maxwin; /* max(win) */ u_int8_t td_scale; /* window scale factor */ + u_int8_t loose; /* used when connection picked up from the middle */ u_int8_t flags; /* per direction options */ }; diff --git a/trunk/include/linux/netfilter/xt_TCPMSS.h b/trunk/include/linux/netfilter/xt_TCPMSS.h deleted file mode 100644 index 53a292cd47f3..000000000000 --- a/trunk/include/linux/netfilter/xt_TCPMSS.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _XT_TCPMSS_H -#define _XT_TCPMSS_H - -struct xt_tcpmss_info { - u_int16_t mss; -}; - -#define XT_TCPMSS_CLAMP_PMTU 0xffff - -#endif /* _XT_TCPMSS_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ip_nat.h b/trunk/include/linux/netfilter_ipv4/ip_nat.h index bbca89aab813..bdf553620ca1 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_nat.h +++ b/trunk/include/linux/netfilter_ipv4/ip_nat.h @@ -16,7 +16,6 @@ enum ip_nat_manip_type #define IP_NAT_RANGE_MAP_IPS 1 #define IP_NAT_RANGE_PROTO_SPECIFIED 2 -#define IP_NAT_RANGE_PROTO_RANDOM 4 /* add randomness to "port" selection */ /* NAT sequence number modifications */ struct ip_nat_seq { diff --git a/trunk/include/linux/netfilter_ipv4/ip_tables.h b/trunk/include/linux/netfilter_ipv4/ip_tables.h index 9527296595cd..98d566c5e32a 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_tables.h +++ b/trunk/include/linux/netfilter_ipv4/ip_tables.h @@ -272,9 +272,25 @@ ipt_get_target(struct ipt_entry *e) #include extern void ipt_init(void) __init; -extern int ipt_register_table(struct xt_table *table, +#define ipt_register_target(tgt) \ +({ (tgt)->family = AF_INET; \ + xt_register_target(tgt); }) +#define ipt_unregister_target(tgt) xt_unregister_target(tgt) + +#define ipt_register_match(mtch) \ +({ (mtch)->family = AF_INET; \ + xt_register_match(mtch); }) +#define ipt_unregister_match(mtch) xt_unregister_match(mtch) + +//#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) +//#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) + +extern int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl); -extern void ipt_unregister_table(struct xt_table *table); +extern void ipt_unregister_table(struct ipt_table *table); + +/* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */ +extern struct ipt_target *ipt_find_target(const char *name, u8 revision); /* Standard entry. */ struct ipt_standard @@ -299,7 +315,7 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb, unsigned int hook, const struct net_device *in, const struct net_device *out, - struct xt_table *table); + struct ipt_table *table); #define IPT_ALIGN(s) XT_ALIGN(s) diff --git a/trunk/include/linux/netfilter_ipv4/ipt_TCPMSS.h b/trunk/include/linux/netfilter_ipv4/ipt_TCPMSS.h index 7a850f945824..aadb39580cd3 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_TCPMSS.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_TCPMSS.h @@ -1,9 +1,10 @@ #ifndef _IPT_TCPMSS_H #define _IPT_TCPMSS_H -#include +struct ipt_tcpmss_info { + u_int16_t mss; +}; -#define ipt_tcpmss_info xt_tcpmss_info -#define IPT_TCPMSS_CLAMP_PMTU XT_TCPMSS_CLAMP_PMTU +#define IPT_TCPMSS_CLAMP_PMTU 0xffff #endif /*_IPT_TCPMSS_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 61aa10412fc8..4aed340401db 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -104,25 +104,6 @@ struct ip6t_entry unsigned char elems[0]; }; -/* Standard entry */ -struct ip6t_standard -{ - struct ip6t_entry entry; - struct ip6t_standard_target target; -}; - -struct ip6t_error_target -{ - struct ip6t_entry_target target; - char errorname[IP6T_FUNCTION_MAXNAMELEN]; -}; - -struct ip6t_error -{ - struct ip6t_entry entry; - struct ip6t_error_target target; -}; - /* * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use @@ -305,14 +286,24 @@ ip6t_get_target(struct ip6t_entry *e) #include extern void ip6t_init(void) __init; -extern int ip6t_register_table(struct xt_table *table, +#define ip6t_register_target(tgt) \ +({ (tgt)->family = AF_INET6; \ + xt_register_target(tgt); }) +#define ip6t_unregister_target(tgt) xt_unregister_target(tgt) + +#define ip6t_register_match(match) \ +({ (match)->family = AF_INET6; \ + xt_register_match(match); }) +#define ip6t_unregister_match(match) xt_unregister_match(match) + +extern int ip6t_register_table(struct ip6t_table *table, const struct ip6t_replace *repl); -extern void ip6t_unregister_table(struct xt_table *table); +extern void ip6t_unregister_table(struct ip6t_table *table); extern unsigned int ip6t_do_table(struct sk_buff **pskb, unsigned int hook, const struct net_device *in, const struct net_device *out, - struct xt_table *table); + struct ip6t_table *table); /* Check for an extension */ extern int ip6t_ext_hdr(u8 nexthdr); diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_mh.h b/trunk/include/linux/netfilter_ipv6/ip6t_mh.h deleted file mode 100644 index b9ca9a5f74d0..000000000000 --- a/trunk/include/linux/netfilter_ipv6/ip6t_mh.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _IP6T_MH_H -#define _IP6T_MH_H - -/* MH matching stuff */ -struct ip6t_mh -{ - u_int8_t types[2]; /* MH type range */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "invflags" field in struct ip6t_mh. */ -#define IP6T_MH_INV_TYPE 0x01 /* Invert the sense of type. */ -#define IP6T_MH_INV_MASK 0x01 /* All possible flags. */ - -#endif /*_IP6T_MH_H*/ diff --git a/trunk/include/linux/pagemap.h b/trunk/include/linux/pagemap.h index 7a8dcb82a699..c3e255bf8594 100644 --- a/trunk/include/linux/pagemap.h +++ b/trunk/include/linux/pagemap.h @@ -76,6 +76,8 @@ extern struct page * find_get_page(struct address_space *mapping, unsigned long index); extern struct page * find_lock_page(struct address_space *mapping, unsigned long index); +extern __deprecated_for_modules struct page * find_trylock_page( + struct address_space *mapping, unsigned long index); extern struct page * find_or_create_page(struct address_space *mapping, unsigned long index, gfp_t gfp_mask); unsigned find_get_pages(struct address_space *mapping, pgoff_t start, diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 920d21e021b6..defdeed20641 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2073,8 +2073,6 @@ #define PCI_VENDOR_ID_PASEMI 0x1959 -#define PCI_VENDOR_ID_ATTANSIC 0x1969 - #define PCI_VENDOR_ID_JMICRON 0x197B #define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 #define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 diff --git a/trunk/include/linux/pfkeyv2.h b/trunk/include/linux/pfkeyv2.h index d9db5f62ee48..265bafab6494 100644 --- a/trunk/include/linux/pfkeyv2.h +++ b/trunk/include/linux/pfkeyv2.h @@ -251,8 +251,7 @@ struct sadb_x_sec_ctx { #define SADB_X_SPDEXPIRE 21 #define SADB_X_SPDDELETE2 22 #define SADB_X_NAT_T_NEW_MAPPING 23 -#define SADB_X_MIGRATE 24 -#define SADB_MAX 24 +#define SADB_MAX 23 /* Security Association flags */ #define SADB_SAFLAGS_PFS 1 @@ -298,7 +297,6 @@ struct sadb_x_sec_ctx { #define SADB_X_EALG_BLOWFISHCBC 7 #define SADB_EALG_NULL 11 #define SADB_X_EALG_AESCBC 12 -#define SADB_X_EALG_CAMELLIACBC 22 #define SADB_EALG_MAX 253 /* last EALG */ /* private allocations should use 249-255 (RFC2407) */ #define SADB_X_EALG_SERPENTCBC 252 /* draft-ietf-ipsec-ciph-aes-cbc-00 */ diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index fcd35a210e7f..92cd38efad7f 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -187,8 +187,7 @@ struct ucred { #define AF_LLC 26 /* Linux LLC */ #define AF_TIPC 30 /* TIPC sockets */ #define AF_BLUETOOTH 31 /* Bluetooth sockets */ -#define AF_IUCV 32 /* IUCV sockets */ -#define AF_MAX 33 /* For now.. */ +#define AF_MAX 32 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -221,7 +220,6 @@ struct ucred { #define PF_LLC AF_LLC #define PF_TIPC AF_TIPC #define PF_BLUETOOTH AF_BLUETOOTH -#define PF_IUCV AF_IUCV #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index 665412c4f4b9..81480e613467 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -699,8 +699,7 @@ enum { NET_X25_CALL_REQUEST_TIMEOUT=2, NET_X25_RESET_REQUEST_TIMEOUT=3, NET_X25_CLEAR_REQUEST_TIMEOUT=4, - NET_X25_ACK_HOLD_BACK_TIMEOUT=5, - NET_X25_FORWARD=6 + NET_X25_ACK_HOLD_BACK_TIMEOUT=5 }; /* /proc/sys/net/token-ring */ diff --git a/trunk/include/linux/tc.h b/trunk/include/linux/tc.h new file mode 100644 index 000000000000..f92511e57cdb --- /dev/null +++ b/trunk/include/linux/tc.h @@ -0,0 +1,141 @@ +/* + * Interface to the TURBOchannel related routines. + * + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 2005 James Simmons + * Copyright (c) 2006 Maciej W. Rozycki + * + * Based on: + * + * "TURBOchannel Firmware Specification", EK-TCAAD-FS-004 + * + * from Digital Equipment Corporation. + * + * This file is subject to the terms and conditions of the GNU + * General Public License. See the file "COPYING" in the main + * directory of this archive for more details. + */ +#ifndef _LINUX_TC_H +#define _LINUX_TC_H + +#include +#include +#include +#include + +/* + * Offsets for the ROM header locations for TURBOchannel cards. + */ +#define TC_OLDCARD 0x3c0000 +#define TC_NEWCARD 0x000000 + +#define TC_ROM_WIDTH 0x3e0 +#define TC_ROM_STRIDE 0x3e4 +#define TC_ROM_SIZE 0x3e8 +#define TC_SLOT_SIZE 0x3ec +#define TC_PATTERN0 0x3f0 +#define TC_PATTERN1 0x3f4 +#define TC_PATTERN2 0x3f8 +#define TC_PATTERN3 0x3fc +#define TC_FIRM_VER 0x400 +#define TC_VENDOR 0x420 +#define TC_MODULE 0x440 +#define TC_FIRM_TYPE 0x460 +#define TC_FLAGS 0x470 +#define TC_ROM_OBJECTS 0x480 + +/* + * Information obtained through the get_tcinfo() PROM call. + */ +struct tcinfo { + s32 revision; /* Hardware revision level. */ + s32 clk_period; /* Clock period in nanoseconds. */ + s32 slot_size; /* Slot size in megabytes. */ + s32 io_timeout; /* I/O timeout in cycles. */ + s32 dma_range; /* DMA address range in megabytes. */ + s32 max_dma_burst; /* Maximum DMA burst length. */ + s32 parity; /* System module supports TC parity. */ + s32 reserved[4]; +}; + +/* + * TURBOchannel bus. + */ +struct tc_bus { + struct list_head devices; /* List of devices on this bus. */ + struct resource resource[2]; /* Address space routed to this bus. */ + + struct device dev; + char name[13]; + resource_size_t slot_base; + resource_size_t ext_slot_base; + resource_size_t ext_slot_size; + int num_tcslots; + struct tcinfo info; +}; + +/* + * TURBOchannel device. + */ +struct tc_dev { + struct list_head node; /* Node in list of all TC devices. */ + struct tc_bus *bus; /* Bus this device is on. */ + struct tc_driver *driver; /* Which driver has allocated this + device. */ + struct device dev; /* Generic device interface. */ + struct resource resource; /* Address space of this device. */ + char vendor[9]; + char name[9]; + char firmware[9]; + int interrupt; + int slot; +}; + +#define to_tc_dev(n) container_of(n, struct tc_dev, dev) + +struct tc_device_id { + char vendor[9]; + char name[9]; +}; + +/* + * TURBOchannel driver. + */ +struct tc_driver { + struct list_head node; + const struct tc_device_id *id_table; + struct device_driver driver; +}; + +#define to_tc_driver(drv) container_of(drv, struct tc_driver, driver) + +/* + * Return TURBOchannel clock frequency in Hz. + */ +static inline unsigned long tc_get_speed(struct tc_bus *tbus) +{ + return 100000 * (10000 / (unsigned long)tbus->info.clk_period); +} + +#ifdef CONFIG_TC + +extern struct bus_type tc_bus_type; + +extern int tc_register_driver(struct tc_driver *tdrv); +extern void tc_unregister_driver(struct tc_driver *tdrv); + +#else /* !CONFIG_TC */ + +static inline int tc_register_driver(struct tc_driver *tdrv) { return 0; } +static inline void tc_unregister_driver(struct tc_driver *tdrv) { } + +#endif /* CONFIG_TC */ + +/* + * These have to be provided by the architecture. + */ +extern int tc_preadb(u8 *valp, void __iomem *addr); +extern int tc_bus_get_info(struct tc_bus *tbus); +extern void tc_device_get_irq(struct tc_dev *tdev); + +#endif /* _LINUX_TC_H */ diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index 29d3089038ab..3cc70d1a3504 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -316,7 +316,7 @@ struct tcp_sock { struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */ struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/ - struct tcp_sack_block_wire recv_sack_cache[4]; + struct tcp_sack_block recv_sack_cache[4]; /* from STCP, retrans queue hinting */ struct sk_buff* lost_skb_hint; diff --git a/trunk/include/linux/wanrouter.h b/trunk/include/linux/wanrouter.h index 3add87465b1f..2cd05013edfc 100644 --- a/trunk/include/linux/wanrouter.h +++ b/trunk/include/linux/wanrouter.h @@ -516,6 +516,9 @@ struct wan_device { /* Public functions available for device drivers */ extern int register_wan_device(struct wan_device *wandev); extern int unregister_wan_device(char *name); +__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev); +int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev, + unsigned short type); /* Proc interface functions. These must not be called by the drivers! */ extern int wanrouter_proc_init(void); @@ -524,6 +527,11 @@ extern int wanrouter_proc_add(struct wan_device *wandev); extern int wanrouter_proc_delete(struct wan_device *wandev); extern int wanrouter_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +extern void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); +extern void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); + + + /* Public Data */ /* list of registered devices */ extern struct wan_device *wanrouter_router_devlist; diff --git a/trunk/include/linux/xfrm.h b/trunk/include/linux/xfrm.h index 15ca89e9961b..9529ea1ae392 100644 --- a/trunk/include/linux/xfrm.h +++ b/trunk/include/linux/xfrm.h @@ -178,9 +178,6 @@ enum { XFRM_MSG_REPORT, #define XFRM_MSG_REPORT XFRM_MSG_REPORT - XFRM_MSG_MIGRATE, -#define XFRM_MSG_MIGRATE XFRM_MSG_MIGRATE - __XFRM_MSG_MAX }; #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) @@ -259,7 +256,6 @@ enum xfrm_attr_type_t { XFRMA_COADDR, /* xfrm_address_t */ XFRMA_LASTUSED, XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ - XFRMA_MIGRATE, __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) @@ -355,19 +351,6 @@ struct xfrm_user_report { struct xfrm_selector sel; }; -struct xfrm_user_migrate { - xfrm_address_t old_daddr; - xfrm_address_t old_saddr; - xfrm_address_t new_daddr; - xfrm_address_t new_saddr; - __u8 proto; - __u8 mode; - __u16 reserved; - __u32 reqid; - __u16 old_family; - __u16 new_family; -}; - #ifndef __KERNEL__ /* backwards compatibility for userspace */ #define XFRMGRP_ACQUIRE 1 @@ -392,8 +375,6 @@ enum xfrm_nlgroups { #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS XFRMNLGRP_REPORT, #define XFRMNLGRP_REPORT XFRMNLGRP_REPORT - XFRMNLGRP_MIGRATE, -#define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE __XFRMNLGRP_MAX }; #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) diff --git a/trunk/include/net/inet_hashtables.h b/trunk/include/net/inet_hashtables.h index d27ee8c0da3f..34cc76e3ddb4 100644 --- a/trunk/include/net/inet_hashtables.h +++ b/trunk/include/net/inet_hashtables.h @@ -34,13 +34,12 @@ #include /* This is for all connections with a full identity, no wildcards. - * One chain is dedicated to TIME_WAIT sockets. - * I'll experiment with dynamic table growth later. + * New scheme, half the table is for TIME_WAIT, the other half is + * for the rest. I'll experiment with dynamic table growth later. */ struct inet_ehash_bucket { rwlock_t lock; struct hlist_head chain; - struct hlist_head twchain; }; /* There are a few simple rules, which allow for local port reuse by @@ -98,7 +97,8 @@ struct inet_hashinfo { * * TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE * - * TIME_WAIT sockets use a separate chain (twchain). + * First half of the table is for sockets not in TIME_WAIT, second half + * is for TIME_WAIT sockets only. */ struct inet_ehash_bucket *ehash; @@ -369,7 +369,7 @@ static inline struct sock * } /* Must check for a TIME_WAIT'er before going to listener hash. */ - sk_for_each(sk, node, &head->twchain) { + sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) goto hit; } diff --git a/trunk/include/net/iucv/af_iucv.h b/trunk/include/net/iucv/af_iucv.h deleted file mode 100644 index 04d1abb72d25..000000000000 --- a/trunk/include/net/iucv/af_iucv.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2006 IBM Corporation - * IUCV protocol stack for Linux on zSeries - * Version 1.0 - * Author(s): Jennifer Hunt - * - */ - -#ifndef __AFIUCV_H -#define __AFIUCV_H - -#include -#include -#include -#include -#include - -#ifndef AF_IUCV -#define AF_IUCV 32 -#define PF_IUCV AF_IUCV -#endif - -/* Connection and socket states */ -enum { - IUCV_CONNECTED = 1, - IUCV_OPEN, - IUCV_BOUND, - IUCV_LISTEN, - IUCV_SEVERED, - IUCV_DISCONN, - IUCV_CLOSED -}; - -#define IUCV_QUEUELEN_DEFAULT 65535 -#define IUCV_CONN_TIMEOUT (HZ * 40) -#define IUCV_DISCONN_TIMEOUT (HZ * 2) -#define IUCV_CONN_IDLE_TIMEOUT (HZ * 60) -#define IUCV_BUFSIZE_DEFAULT 32768 - -/* IUCV socket address */ -struct sockaddr_iucv { - sa_family_t siucv_family; - unsigned short siucv_port; /* Reserved */ - unsigned int siucv_addr; /* Reserved */ - char siucv_nodeid[8]; /* Reserved */ - char siucv_user_id[8]; /* Guest User Id */ - char siucv_name[8]; /* Application Name */ -}; - - -/* Common socket structures and functions */ - -#define iucv_sk(__sk) ((struct iucv_sock *) __sk) - -struct iucv_sock { - struct sock sk; - char src_user_id[8]; - char src_name[8]; - char dst_user_id[8]; - char dst_name[8]; - struct list_head accept_q; - struct sock *parent; - struct iucv_path *path; - struct sk_buff_head send_skb_q; - unsigned int send_tag; -}; - -struct iucv_sock_list { - struct hlist_head head; - rwlock_t lock; - atomic_t autobind_name; -}; - -static void iucv_sock_destruct(struct sock *sk); -static void iucv_sock_cleanup_listen(struct sock *parent); -static void iucv_sock_kill(struct sock *sk); -static void iucv_sock_close(struct sock *sk); -static int iucv_sock_create(struct socket *sock, int proto); -static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr, - int addr_len); -static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, - int alen, int flags); -static int iucv_sock_listen(struct socket *sock, int backlog); -static int iucv_sock_accept(struct socket *sock, struct socket *newsock, - int flags); -static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr, - int *len, int peer); -static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len); -static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags); -unsigned int iucv_sock_poll(struct file *file, struct socket *sock, - poll_table *wait); -static int iucv_sock_release(struct socket *sock); -static int iucv_sock_shutdown(struct socket *sock, int how); - -void iucv_sock_link(struct iucv_sock_list *l, struct sock *s); -void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *s); -int iucv_sock_wait_state(struct sock *sk, int state, int state2, - unsigned long timeo); -int iucv_sock_wait_cnt(struct sock *sk, unsigned long timeo); -void iucv_accept_enqueue(struct sock *parent, struct sock *sk); -void iucv_accept_unlink(struct sock *sk); -struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock); - -#endif /* __IUCV_H */ diff --git a/trunk/include/net/iucv/iucv.h b/trunk/include/net/iucv/iucv.h deleted file mode 100644 index 746e7416261e..000000000000 --- a/trunk/include/net/iucv/iucv.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * drivers/s390/net/iucv.h - * IUCV base support. - * - * S390 version - * Copyright 2000, 2006 IBM Corporation - * Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) - * Xenia Tkatschow (xenia@us.ibm.com) - * Rewritten for af_iucv: - * Martin Schwidefsky - * - * - * Functionality: - * To explore any of the IUCV functions, one must first register their - * program using iucv_register(). Once your program has successfully - * completed a register, it can exploit the other functions. - * For furthur reference on all IUCV functionality, refer to the - * CP Programming Services book, also available on the web thru - * www.ibm.com/s390/vm/pubs, manual # SC24-5760 - * - * Definition of Return Codes - * - All positive return codes including zero are reflected back - * from CP. The definition of each return code can be found in - * CP Programming Services book. - * - Return Code of: - * -EINVAL: Invalid value - * -ENOMEM: storage allocation failed - */ - -#include -#include - -/* - * IUCV option flags usable by device drivers: - * - * IUCV_IPRMDATA Indicates that your program can handle a message in the - * parameter list / a message is sent in the parameter list. - * Used for iucv_path_accept, iucv_path_connect, - * iucv_message_reply, iucv_message_send, iucv_message_send2way. - * IUCV_IPQUSCE Indicates that you do not want to receive messages on this - * path until an iucv_path_resume is issued. - * Used for iucv_path_accept, iucv_path_connect. - * IUCV_IPBUFLST Indicates that an address list is used for the message data. - * Used for iucv_message_receive, iucv_message_send, - * iucv_message_send2way. - * IUCV_IPPRTY Specifies that you want to send priority messages. - * Used for iucv_path_accept, iucv_path_connect, - * iucv_message_reply, iucv_message_send, iucv_message_send2way. - * IUCV_IPSYNC Indicates a synchronous send request. - * Used for iucv_message_send, iucv_message_send2way. - * IUCV_IPANSLST Indicates that an address list is used for the reply data. - * Used for iucv_message_reply, iucv_message_send2way. - * IUCV_IPLOCAL Specifies that the communication partner has to be on the - * local system. If local is specified no target class can be - * specified. - * Used for iucv_path_connect. - * - * All flags are defined in the input field IPFLAGS1 of each function - * and can be found in CP Programming Services. - */ -#define IUCV_IPRMDATA 0x80 -#define IUCV_IPQUSCE 0x40 -#define IUCV_IPBUFLST 0x40 -#define IUCV_IPPRTY 0x20 -#define IUCV_IPANSLST 0x08 -#define IUCV_IPSYNC 0x04 -#define IUCV_IPLOCAL 0x01 - -/* - * iucv_array : Defines buffer array. - * Inside the array may be 31- bit addresses and 31-bit lengths. - * Use a pointer to an iucv_array as the buffer, reply or answer - * parameter on iucv_message_send, iucv_message_send2way, iucv_message_receive - * and iucv_message_reply if IUCV_IPBUFLST or IUCV_IPANSLST are used. - */ -struct iucv_array { - u32 address; - u32 length; -} __attribute__ ((aligned (8))); - -extern struct bus_type iucv_bus; -extern struct device *iucv_root; - -/* - * struct iucv_path - * pathid: 16 bit path identification - * msglim: 16 bit message limit - * flags: properties of the path: IPRMDATA, IPQUSCE, IPPRTY - * handler: address of iucv handler structure - * private: private information of the handler associated with the path - * list: list_head for the iucv_handler path list. - */ -struct iucv_path { - u16 pathid; - u16 msglim; - u8 flags; - void *private; - struct iucv_handler *handler; - struct list_head list; -}; - -/* - * struct iucv_message - * id: 32 bit message id - * audit: 32 bit error information of purged or replied messages - * class: 32 bit target class of a message (source class for replies) - * tag: 32 bit tag to be associated with the message - * length: 32 bit length of the message / reply - * reply_size: 32 bit maximum allowed length of the reply - * rmmsg: 8 byte inline message - * flags: message properties (IUCV_IPPRTY) - */ -struct iucv_message { - u32 id; - u32 audit; - u32 class; - u32 tag; - u32 length; - u32 reply_size; - u8 rmmsg[8]; - u8 flags; -}; - -/* - * struct iucv_handler - * - * A vector of functions that handle IUCV interrupts. Each functions gets - * a parameter area as defined by the CP Programming Services and private - * pointer that is provided by the user of the interface. - */ -struct iucv_handler { - /* - * The path_pending function is called after an iucv interrupt - * type 0x01 has been received. The base code allocates a path - * structure and "asks" the handler if this path belongs to the - * handler. To accept the path the path_pending function needs - * to call iucv_path_accept and return 0. If the callback returns - * a value != 0 the iucv base code will continue with the next - * handler. The order in which the path_pending functions are - * called is the order of the registration of the iucv handlers - * to the base code. - */ - int (*path_pending)(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); - /* - * The path_complete function is called after an iucv interrupt - * type 0x02 has been received for a path that has been established - * for this handler with iucv_path_connect and got accepted by the - * peer with iucv_path_accept. - */ - void (*path_complete)(struct iucv_path *, u8 ipuser[16]); - /* - * The path_severed function is called after an iucv interrupt - * type 0x03 has been received. The communication peer shutdown - * his end of the communication path. The path still exists and - * remaining messages can be received until a iucv_path_sever - * shuts down the other end of the path as well. - */ - void (*path_severed)(struct iucv_path *, u8 ipuser[16]); - /* - * The path_quiesced function is called after an icuv interrupt - * type 0x04 has been received. The communication peer has quiesced - * the path. Delivery of messages is stopped until iucv_path_resume - * has been called. - */ - void (*path_quiesced)(struct iucv_path *, u8 ipuser[16]); - /* - * The path_resumed function is called after an icuv interrupt - * type 0x05 has been received. The communication peer has resumed - * the path. - */ - void (*path_resumed)(struct iucv_path *, u8 ipuser[16]); - /* - * The message_pending function is called after an icuv interrupt - * type 0x06 or type 0x07 has been received. A new message is - * availabe and can be received with iucv_message_receive. - */ - void (*message_pending)(struct iucv_path *, struct iucv_message *); - /* - * The message_complete function is called after an icuv interrupt - * type 0x08 or type 0x09 has been received. A message send with - * iucv_message_send2way has been replied to. The reply can be - * received with iucv_message_receive. - */ - void (*message_complete)(struct iucv_path *, struct iucv_message *); - - struct list_head list; - struct list_head paths; -}; - -/** - * iucv_register: - * @handler: address of iucv handler structure - * @smp: != 0 indicates that the handler can deal with out of order messages - * - * Registers a driver with IUCV. - * - * Returns 0 on success, -ENOMEM if the memory allocation for the pathid - * table failed, or -EIO if IUCV_DECLARE_BUFFER failed on all cpus. - */ -int iucv_register(struct iucv_handler *handler, int smp); - -/** - * iucv_unregister - * @handler: address of iucv handler structure - * @smp: != 0 indicates that the handler can deal with out of order messages - * - * Unregister driver from IUCV. - */ -void iucv_unregister(struct iucv_handler *handle, int smp); - -/** - * iucv_path_alloc - * @msglim: initial message limit - * @flags: initial flags - * @gfp: kmalloc allocation flag - * - * Allocate a new path structure for use with iucv_connect. - * - * Returns NULL if the memory allocation failed or a pointer to the - * path structure. - */ -static inline struct iucv_path *iucv_path_alloc(u16 msglim, u8 flags, gfp_t gfp) -{ - struct iucv_path *path; - - path = kzalloc(sizeof(struct iucv_path), gfp); - if (path) { - path->msglim = msglim; - path->flags = flags; - } - return path; -} - -/** - * iucv_path_free - * @path: address of iucv path structure - * - * Frees a path structure. - */ -static inline void iucv_path_free(struct iucv_path *path) -{ - kfree(path); -} - -/** - * iucv_path_accept - * @path: address of iucv path structure - * @handler: address of iucv handler structure - * @userdata: 16 bytes of data reflected to the communication partner - * @private: private data passed to interrupt handlers for this path - * - * This function is issued after the user received a connection pending - * external interrupt and now wishes to complete the IUCV communication path. - * - * Returns the result of the CP IUCV call. - */ -int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, - u8 userdata[16], void *private); - -/** - * iucv_path_connect - * @path: address of iucv path structure - * @handler: address of iucv handler structure - * @userid: 8-byte user identification - * @system: 8-byte target system identification - * @userdata: 16 bytes of data reflected to the communication partner - * @private: private data passed to interrupt handlers for this path - * - * This function establishes an IUCV path. Although the connect may complete - * successfully, you are not able to use the path until you receive an IUCV - * Connection Complete external interrupt. - * - * Returns the result of the CP IUCV call. - */ -int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, - u8 userid[8], u8 system[8], u8 userdata[16], - void *private); - -/** - * iucv_path_quiesce: - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function temporarily suspends incoming messages on an IUCV path. - * You can later reactivate the path by invoking the iucv_resume function. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]); - -/** - * iucv_path_resume: - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function resumes incoming messages on an IUCV path that has - * been stopped with iucv_path_quiesce. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_resume(struct iucv_path *path, u8 userdata[16]); - -/** - * iucv_path_sever - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function terminates an IUCV path. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_sever(struct iucv_path *path, u8 userdata[16]); - -/** - * iucv_message_purge - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @srccls: source class of message - * - * Cancels a message you have sent. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg, - u32 srccls); - -/** - * iucv_message_receive - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: flags that affect how the message is received (IUCV_IPBUFLST) - * @buffer: address of data buffer or address of struct iucv_array - * @size: length of data buffer - * @residual: - * - * This function receives messages that are being sent to you over - * established paths. This function will deal with RMDATA messages - * embedded in struct iucv_message as well. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg, - u8 flags, void *buffer, size_t size, size_t *residual); - -/** - * iucv_message_reject - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * - * The reject function refuses a specified message. Between the time you - * are notified of a message and the time that you complete the message, - * the message may be rejected. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg); - -/** - * iucv_message_reply - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the reply is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST) - * @reply: address of data buffer or address of struct iucv_array - * @size: length of reply data buffer - * - * This function responds to the two-way messages that you receive. You - * must identify completely the message to which you wish to reply. ie, - * pathid, msgid, and trgcls. Prmmsg signifies the data is moved into - * the parameter list. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg, - u8 flags, void *reply, size_t size); - -/** - * iucv_message_send - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST) - * @srccls: source class of message - * @buffer: address of data buffer or address of struct iucv_array - * @size: length of send buffer - * - * This function transmits data to another application. Data to be - * transmitted is in a buffer and this is a one-way message and the - * receiver will not reply to the message. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_send(struct iucv_path *path, struct iucv_message *msg, - u8 flags, u32 srccls, void *buffer, size_t size); - -/** - * iucv_message_send2way - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the message is sent and the reply is received - * (IUCV_IPRMDATA, IUCV_IPBUFLST, IUCV_IPPRTY, IUCV_ANSLST) - * @srccls: source class of message - * @buffer: address of data buffer or address of struct iucv_array - * @size: length of send buffer - * @ansbuf: address of answer buffer or address of struct iucv_array - * @asize: size of reply buffer - * - * This function transmits data to another application. Data to be - * transmitted is in a buffer. The receiver of the send is expected to - * reply to the message and a buffer is provided into which IUCV moves - * the reply to this message. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg, - u8 flags, u32 srccls, void *buffer, size_t size, - void *answer, size_t asize, size_t *residual); diff --git a/trunk/include/net/netfilter/nf_conntrack.h b/trunk/include/net/netfilter/nf_conntrack.h index 68ec27490c20..bd01b4633ee2 100644 --- a/trunk/include/net/netfilter/nf_conntrack.h +++ b/trunk/include/net/netfilter/nf_conntrack.h @@ -45,7 +45,6 @@ union nf_conntrack_expect_proto { #include #include #include -#include /* per conntrack: application helper private data */ union nf_conntrack_help { @@ -53,7 +52,6 @@ union nf_conntrack_help { struct nf_ct_ftp_master ct_ftp_info; struct nf_ct_pptp_master ct_pptp_info; struct nf_ct_h323_master ct_h323_info; - struct nf_ct_sane_master ct_sane_info; }; #include diff --git a/trunk/include/net/netfilter/nf_nat.h b/trunk/include/net/netfilter/nf_nat.h index bc57dd7b9b5c..61c62068ca6b 100644 --- a/trunk/include/net/netfilter/nf_nat.h +++ b/trunk/include/net/netfilter/nf_nat.h @@ -16,7 +16,6 @@ enum nf_nat_manip_type #define IP_NAT_RANGE_MAP_IPS 1 #define IP_NAT_RANGE_PROTO_SPECIFIED 2 -#define IP_NAT_RANGE_PROTO_RANDOM 4 /* NAT sequence number modifications */ struct nf_nat_seq { diff --git a/trunk/include/net/route.h b/trunk/include/net/route.h index 1440bdb5a27d..486e37aff06c 100644 --- a/trunk/include/net/route.h +++ b/trunk/include/net/route.h @@ -146,8 +146,7 @@ static inline char rt_tos2priority(u8 tos) static inline int ip_route_connect(struct rtable **rp, __be32 dst, __be32 src, u32 tos, int oif, u8 protocol, - __be16 sport, __be16 dport, struct sock *sk, - int flags) + __be16 sport, __be16 dport, struct sock *sk) { struct flowi fl = { .oif = oif, .nl_u = { .ip4_u = { .daddr = dst, @@ -169,7 +168,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(rp, &fl, sk, flags); + return ip_route_output_flow(rp, &fl, sk, 0); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 5c472f255b77..cd8fa0c858ae 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -802,8 +802,9 @@ static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) /* * Calculate(/check) TCP checksum */ -static inline __sum16 tcp_v4_check(int len, __be32 saddr, - __be32 daddr, __wsum base) +static inline __sum16 tcp_v4_check(struct tcphdr *th, int len, + __be32 saddr, __be32 daddr, + __wsum base) { return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); } diff --git a/trunk/include/net/x25.h b/trunk/include/net/x25.h index fc3f03d976f8..e47fe440d9d7 100644 --- a/trunk/include/net/x25.h +++ b/trunk/include/net/x25.h @@ -161,14 +161,6 @@ struct x25_sock { unsigned long vc_facil_mask; /* inc_call facilities mask */ }; -struct x25_forward { - struct list_head node; - unsigned int lci; - struct net_device *dev1; - struct net_device *dev2; - atomic_t refcnt; -}; - static inline struct x25_sock *x25_sk(const struct sock *sk) { return (struct x25_sock *)sk; @@ -180,7 +172,6 @@ extern int sysctl_x25_call_request_timeout; extern int sysctl_x25_reset_request_timeout; extern int sysctl_x25_clear_request_timeout; extern int sysctl_x25_ack_holdback_timeout; -extern int sysctl_x25_forward; extern int x25_addr_ntoa(unsigned char *, struct x25_address *, struct x25_address *); @@ -207,13 +198,6 @@ extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_dte_facilities *); extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); -/* x25_forward.c */ -extern void x25_clear_forward_by_lci(unsigned int lci); -extern void x25_clear_forward_by_dev(struct net_device *); -extern int x25_forward_data(int, struct x25_neigh *, struct sk_buff *); -extern int x25_forward_call(struct x25_address *, struct x25_neigh *, - struct sk_buff *, int); - /* x25_in.c */ extern int x25_process_rx_frame(struct sock *, struct sk_buff *); extern int x25_backlog_rcv(struct sock *, struct sk_buff *); @@ -298,8 +282,6 @@ extern struct hlist_head x25_list; extern rwlock_t x25_list_lock; extern struct list_head x25_route_list; extern rwlock_t x25_route_list_lock; -extern struct list_head x25_forward_list; -extern rwlock_t x25_forward_list_lock; extern int x25_proc_init(void); extern void x25_proc_exit(void); diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 16924cb772c9..e4765413cf80 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -252,13 +252,10 @@ struct xfrm_state_afinfo { xfrm_address_t *daddr, xfrm_address_t *saddr); int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); - int (*output)(struct sk_buff *skb); }; extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); -extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); -extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); extern void xfrm_state_delete_tunnel(struct xfrm_state *x); @@ -362,19 +359,6 @@ struct xfrm_policy struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; }; -struct xfrm_migrate { - xfrm_address_t old_daddr; - xfrm_address_t old_saddr; - xfrm_address_t new_daddr; - xfrm_address_t new_saddr; - u8 proto; - u8 mode; - u16 reserved; - u32 reqid; - u16 old_family; - u16 new_family; -}; - #define XFRM_KM_TIMEOUT 30 /* which seqno */ #define XFRM_REPLAY_SEQ 1 @@ -401,7 +385,6 @@ struct xfrm_mgr int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c); int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); - int (*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles); }; extern int xfrm_register_km(struct xfrm_mgr *km); @@ -1002,16 +985,6 @@ extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); extern void xfrm_init_pmtu(struct dst_entry *dst); -#ifdef CONFIG_XFRM_MIGRATE -extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_bundles); -extern struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m); -extern struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, - struct xfrm_migrate *m); -extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_bundles); -#endif - extern wait_queue_head_t km_waitq; extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); @@ -1077,25 +1050,5 @@ static inline void xfrm_aevent_doreplay(struct xfrm_state *x) xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); } -#ifdef CONFIG_XFRM_MIGRATE -static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) -{ - return (struct xfrm_algo *)kmemdup(orig, sizeof(*orig) + orig->alg_key_len, GFP_KERNEL); -} - -static inline void xfrm_states_put(struct xfrm_state **states, int n) -{ - int i; - for (i = 0; i < n; i++) - xfrm_state_put(*(states + i)); -} - -static inline void xfrm_states_delete(struct xfrm_state **states, int n) -{ - int i; - for (i = 0; i < n; i++) - xfrm_state_delete(*(states + i)); -} -#endif #endif /* _NET_XFRM_H */ diff --git a/trunk/include/scsi/iscsi_proto.h b/trunk/include/scsi/iscsi_proto.h index 4a44278ed768..02f6e4b9e693 100644 --- a/trunk/include/scsi/iscsi_proto.h +++ b/trunk/include/scsi/iscsi_proto.h @@ -40,14 +40,6 @@ } #define zero_data(p) {p[0]=0;p[1]=0;p[2]=0;} -/* initiator tags; opaque for target */ -typedef uint32_t __bitwise__ itt_t; -/* below makes sense only for initiator that created this tag */ -#define build_itt(itt, id, age) ((__force itt_t)\ - ((itt) | ((id) << ISCSI_CID_SHIFT) | ((age) << ISCSI_AGE_SHIFT))) -#define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK) -#define RESERVED_ITT ((__force itt_t)0xffffffff) - /* * iSCSI Template Message Header */ @@ -58,7 +50,7 @@ struct iscsi_hdr { uint8_t hlength; /* AHSs total length */ uint8_t dlength[3]; /* Data length */ uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag, opaque for target */ + __be32 itt; /* Initiator Task Tag */ __be32 ttt; /* Target Task Tag */ __be32 statsn; __be32 exp_statsn; @@ -119,7 +111,7 @@ struct iscsi_cmd { uint8_t hlength; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 data_length; __be32 cmdsn; __be32 exp_statsn; @@ -156,7 +148,7 @@ struct iscsi_cmd_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 rsvd1; __be32 statsn; __be32 exp_cmdsn; @@ -214,7 +206,7 @@ struct iscsi_nopout { uint8_t rsvd3; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 ttt; /* Target Transfer Tag */ __be32 cmdsn; __be32 exp_statsn; @@ -229,7 +221,7 @@ struct iscsi_nopin { uint8_t rsvd3; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 ttt; /* Target Transfer Tag */ __be32 statsn; __be32 exp_cmdsn; @@ -245,8 +237,8 @@ struct iscsi_tm { uint8_t hlength; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag */ - itt_t rtt; /* Reference Task Tag */ + __be32 itt; /* Initiator Task Tag */ + __be32 rtt; /* Reference Task Tag */ __be32 cmdsn; __be32 exp_statsn; __be32 refcmdsn; @@ -275,8 +267,8 @@ struct iscsi_tm_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd2[8]; - itt_t itt; /* Initiator Task Tag */ - itt_t rtt; /* Reference Task Tag */ + __be32 itt; /* Initiator Task Tag */ + __be32 rtt; /* Reference Task Tag */ __be32 statsn; __be32 exp_cmdsn; __be32 max_cmdsn; @@ -301,7 +293,7 @@ struct iscsi_r2t_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 ttt; /* Target Transfer Tag */ __be32 statsn; __be32 exp_cmdsn; @@ -319,7 +311,7 @@ struct iscsi_data { uint8_t rsvd3; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; + __be32 itt; __be32 ttt; __be32 rsvd4; __be32 exp_statsn; @@ -339,7 +331,7 @@ struct iscsi_data_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t lun[8]; - itt_t itt; + __be32 itt; __be32 ttt; __be32 statsn; __be32 exp_cmdsn; @@ -363,7 +355,7 @@ struct iscsi_text { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd4[8]; - itt_t itt; + __be32 itt; __be32 ttt; __be32 cmdsn; __be32 exp_statsn; @@ -381,7 +373,7 @@ struct iscsi_text_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd4[8]; - itt_t itt; + __be32 itt; __be32 ttt; __be32 statsn; __be32 exp_cmdsn; @@ -400,7 +392,7 @@ struct iscsi_login { uint8_t dlength[3]; uint8_t isid[6]; /* Initiator Session ID */ __be16 tsih; /* Target Session Handle */ - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be16 cid; __be16 rsvd3; __be32 cmdsn; @@ -429,7 +421,7 @@ struct iscsi_login_rsp { uint8_t dlength[3]; uint8_t isid[6]; /* Initiator Session ID */ __be16 tsih; /* Target Session Handle */ - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 rsvd3; __be32 statsn; __be32 exp_cmdsn; @@ -486,7 +478,7 @@ struct iscsi_logout { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd2[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be16 cid; uint8_t rsvd3[2]; __be32 cmdsn; @@ -513,7 +505,7 @@ struct iscsi_logout_rsp { uint8_t hlength; uint8_t dlength[3]; uint8_t rsvd3[8]; - itt_t itt; /* Initiator Task Tag */ + __be32 itt; /* Initiator Task Tag */ __be32 rsvd4; __be32 statsn; __be32 exp_cmdsn; @@ -536,7 +528,7 @@ struct iscsi_snack { uint8_t opcode; uint8_t flags; uint8_t rsvd2[14]; - itt_t itt; + __be32 itt; __be32 begrun; __be32 runlength; __be32 exp_statsn; diff --git a/trunk/include/sound/ac97_codec.h b/trunk/include/sound/ac97_codec.h index 246ac23534bd..33720397a904 100644 --- a/trunk/include/sound/ac97_codec.h +++ b/trunk/include/sound/ac97_codec.h @@ -375,7 +375,6 @@ #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */ #define AC97_SCAP_NO_SPDIF (1<<9) /* don't build SPDIF controls */ #define AC97_SCAP_EAPD_LED (1<<10) /* EAPD as mute LED */ -#define AC97_SCAP_POWER_SAVE (1<<11) /* capable for aggresive power-saving */ /* ac97->flags */ #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ @@ -426,7 +425,6 @@ struct snd_ac97_build_ops { struct snd_ac97_bus_ops { void (*reset) (struct snd_ac97 *ac97); - void (*warm_reset)(struct snd_ac97 *ac97); void (*write) (struct snd_ac97 *ac97, unsigned short reg, unsigned short val); unsigned short (*read) (struct snd_ac97 *ac97, unsigned short reg); void (*wait) (struct snd_ac97 *ac97); @@ -503,7 +501,6 @@ struct snd_ac97 { unsigned short id[3]; // codec IDs (lower 16-bit word) unsigned short pcmreg[3]; // PCM registers unsigned short codec_cfg[3]; // CODEC_CFG bits - unsigned char swap_mic_linein; // AD1986/AD1986A only } ad18xx; unsigned int dev_flags; /* device specific */ } spec; @@ -513,6 +510,7 @@ struct snd_ac97 { #ifdef CONFIG_SND_AC97_POWER_SAVE unsigned int power_up; /* power states */ + struct workqueue_struct *power_workq; struct delayed_work power_work; #endif struct device dev; diff --git a/trunk/include/sound/ad1848.h b/trunk/include/sound/ad1848.h index b2c3f00a9b35..c8de6f83338f 100644 --- a/trunk/include/sound/ad1848.h +++ b/trunk/include/sound/ad1848.h @@ -185,7 +185,7 @@ struct ad1848_mix_elem { int index; int type; unsigned long private_value; - const unsigned int *tlv; + unsigned int *tlv; }; #define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \ diff --git a/trunk/include/sound/ak4114.h b/trunk/include/sound/ak4114.h index c149d3b2558b..2ee061625fd0 100644 --- a/trunk/include/sound/ak4114.h +++ b/trunk/include/sound/ak4114.h @@ -181,6 +181,7 @@ struct ak4114 { unsigned long ccrc_errors; unsigned char rcs0; unsigned char rcs1; + struct workqueue_struct *workqueue; struct delayed_work work; void *change_callback_private; void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1); @@ -188,7 +189,7 @@ struct ak4114 { int snd_ak4114_create(struct snd_card *card, ak4114_read_t *read, ak4114_write_t *write, - const unsigned char pgm[7], const unsigned char txcsb[5], + unsigned char pgm[7], unsigned char txcsb[5], void *private_data, struct ak4114 **r_ak4114); void snd_ak4114_reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char mask, unsigned char val); void snd_ak4114_reinit(struct ak4114 *ak4114); diff --git a/trunk/include/sound/ak4117.h b/trunk/include/sound/ak4117.h index d650d52e3d29..2b96c32f06fd 100644 --- a/trunk/include/sound/ak4117.h +++ b/trunk/include/sound/ak4117.h @@ -178,7 +178,7 @@ struct ak4117 { }; int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write, - const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117); + unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117); void snd_ak4117_reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char mask, unsigned char val); void snd_ak4117_reinit(struct ak4117 *ak4117); int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *capture_substream); diff --git a/trunk/include/sound/ak4xxx-adda.h b/trunk/include/sound/ak4xxx-adda.h index aa49dda4f410..d0deca669b92 100644 --- a/trunk/include/sound/ak4xxx-adda.h +++ b/trunk/include/sound/ak4xxx-adda.h @@ -50,8 +50,6 @@ struct snd_akm4xxx_adc_channel { char *name; /* capture gain volume label */ char *switch_name; /* capture switch */ unsigned int num_channels; - char *selector_name; /* capture source select label */ - const char **input_names; /* capture source names (NULL terminated) */ }; struct snd_akm4xxx { @@ -71,8 +69,8 @@ struct snd_akm4xxx { } type; /* (array) information of combined codecs */ - const struct snd_akm4xxx_dac_channel *dac_info; - const struct snd_akm4xxx_adc_channel *adc_info; + struct snd_akm4xxx_dac_channel *dac_info; + struct snd_akm4xxx_adc_channel *adc_info; struct snd_ak4xxx_ops ops; }; diff --git a/trunk/include/sound/control.h b/trunk/include/sound/control.h index 72e759f619b1..1de148b0fd94 100644 --- a/trunk/include/sound/control.h +++ b/trunk/include/sound/control.h @@ -49,7 +49,7 @@ struct snd_kcontrol_new { snd_kcontrol_put_t *put; union { snd_kcontrol_tlv_rw_t *c; - const unsigned int *p; + unsigned int *p; } tlv; unsigned long private_value; }; @@ -69,7 +69,7 @@ struct snd_kcontrol { snd_kcontrol_put_t *put; union { snd_kcontrol_tlv_rw_t *c; - const unsigned int *p; + unsigned int *p; } tlv; unsigned long private_value; void *private_data; @@ -108,6 +108,7 @@ typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card, void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id); +struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol * kcontrol, unsigned int access); struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data); void snd_ctl_free_one(struct snd_kcontrol * kcontrol); int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol); diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index 4b9e609975ab..521f036cce99 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -211,40 +211,9 @@ extern struct class *sound_class; void snd_request_card(int card); -int snd_register_device_for_dev(int type, struct snd_card *card, - int dev, - const struct file_operations *f_ops, - void *private_data, - const char *name, - struct device *device); - -/** - * snd_register_device - Register the ALSA device file for the card - * @type: the device type, SNDRV_DEVICE_TYPE_XXX - * @card: the card instance - * @dev: the device index - * @f_ops: the file operations - * @private_data: user pointer for f_ops->open() - * @name: the device file name - * - * Registers an ALSA device file for the given card. - * The operators have to be set in reg parameter. - * - * This function uses the card's device pointer to link to the - * correct &struct device. - * - * Returns zero if successful, or a negative error code on failure. - */ -static inline int snd_register_device(int type, struct snd_card *card, int dev, - const struct file_operations *f_ops, - void *private_data, - const char *name) -{ - return snd_register_device_for_dev(type, card, dev, f_ops, - private_data, name, - snd_card_get_device_link(card)); -} - +int snd_register_device(int type, struct snd_card *card, int dev, + const struct file_operations *f_ops, void *private_data, + const char *name); int snd_unregister_device(int type, struct snd_card *card, int dev); void *snd_lookup_minor_data(unsigned int minor, int type); int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, @@ -427,29 +396,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) #endif #endif -/* PCI quirk list helper */ -struct snd_pci_quirk { - unsigned short subvendor; /* PCI subvendor ID */ - unsigned short subdevice; /* PCI subdevice ID */ - int value; /* value */ -#ifdef CONFIG_SND_DEBUG_DETECT - const char *name; /* name of the device (optional) */ -#endif -}; - -#define _SND_PCI_QUIRK_ID(vend,dev) \ - .subvendor = (vend), .subdevice = (dev) -#define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)} -#ifdef CONFIG_SND_DEBUG_DETECT -#define SND_PCI_QUIRK(vend,dev,xname,val) \ - {_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)} -#else -#define SND_PCI_QUIRK(vend,dev,xname,val) \ - {_SND_PCI_QUIRK_ID(vend, dev), .value = (val)} -#endif - -const struct snd_pci_quirk * -snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list); - +#include "typedefs.h" #endif /* __SOUND_CORE_H */ diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h index eb7ce96ddf3a..3d3c1514cf71 100644 --- a/trunk/include/sound/emu10k1.h +++ b/trunk/include/sound/emu10k1.h @@ -188,35 +188,7 @@ #define HCFG_LEGACYINT 0x00200000 /* 1 = legacy event captured. Write 1 to clear. */ /* NOTE: The rest of the bits in this register */ /* _are_ relevant under Linux. */ -#define HCFG_PUSH_BUTTON_ENABLE 0x00100000 /* Enables Volume Inc/Dec and Mute functions */ -#define HCFG_BAUD_RATE 0x00080000 /* 0 = 48kHz, 1 = 44.1kHz */ -#define HCFG_EXPANDED_MEM 0x00040000 /* 1 = any 16M of 4G addr, 0 = 32M of 2G addr */ -#define HCFG_CODECFORMAT_MASK 0x00030000 /* CODEC format */ - -/* Specific to Alice2, CA0102 */ -#define HCFG_CODECFORMAT_AC97_1 0x00000000 /* AC97 CODEC format -- Ver 1.03 */ -#define HCFG_CODECFORMAT_AC97_2 0x00010000 /* AC97 CODEC format -- Ver 2.1 */ -#define HCFG_AUTOMUTE_ASYNC 0x00008000 /* When set, the async sample rate convertors */ - /* will automatically mute their output when */ - /* they are not rate-locked to the external */ - /* async audio source */ -#define HCFG_AUTOMUTE_SPDIF 0x00004000 /* When set, the async sample rate convertors */ - /* will automatically mute their output when */ - /* the SPDIF V-bit indicates invalid audio */ -#define HCFG_EMU32_SLAVE 0x00002000 /* 0 = Master, 1 = Slave. Slave for EMU1010 */ -#define HCFG_SLOW_RAMP 0x00001000 /* Increases Send Smoothing time constant */ -/* 0x00000800 not used on Alice2 */ -#define HCFG_PHASE_TRACK_MASK 0x00000700 /* When set, forces corresponding input to */ - /* phase track the previous input. */ - /* I2S0 can phase track the last S/PDIF input */ -#define HCFG_I2S_ASRC_ENABLE 0x00000070 /* When set, enables asynchronous sample rate */ - /* conversion for the corresponding */ - /* I2S format input */ -/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc. */ - - - -/* Older chips */ +#define HCFG_CODECFORMAT_MASK 0x00070000 /* CODEC format */ #define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */ #define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */ #define HCFG_GPINPUT0 0x00004000 /* External pin112 */ @@ -460,7 +432,6 @@ #define FXRT_CHANNELC 0x0f000000 /* Effects send bus number for channel's effects send C */ #define FXRT_CHANNELD 0xf0000000 /* Effects send bus number for channel's effects send D */ -#define A_HR 0x0b /* High Resolution. 24bit playback from host to DSP. */ #define MAPA 0x0c /* Cache map A */ #define MAPB 0x0d /* Cache map B */ @@ -468,8 +439,6 @@ #define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */ #define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */ -/* 0x0e, 0x0f: Not used */ - #define ENVVOL 0x10 /* Volume envelope register */ #define ENVVOL_MASK 0x0000ffff /* Current value of volume envelope state variable */ /* 0x8000-n == 666*n usec delay */ @@ -558,7 +527,7 @@ /* NOTE: All channels contain internal variables; do */ /* not write to these locations. */ -/* 0x1f: not used */ +/* 1f something */ #define CD0 0x20 /* Cache data 0 register */ #define CD1 0x21 /* Cache data 1 register */ @@ -628,8 +597,6 @@ #define FXWC_SPDIFLEFT (1<<22) /* 0x00400000 */ #define FXWC_SPDIFRIGHT (1<<23) /* 0x00800000 */ -#define A_TBLSZ ` 0x43 /* Effects Tank Internal Table Size. Only low byte or register used */ - #define TCBS 0x44 /* Tank cache buffer size register */ #define TCBS_MASK 0x00000007 /* Tank cache buffer size field */ #define TCBS_BUFFSIZE_16K 0x00000000 @@ -650,7 +617,7 @@ #define FXBA 0x47 /* FX Buffer Address */ #define FXBA_MASK 0xfffff000 /* 20 bit base address */ -#define A_HWM 0x48 /* High PCI Water Mark - word access, defaults to 3f */ +/* 0x48 something - word access, defaults to 3f */ #define MICBS 0x49 /* Microphone buffer size register */ @@ -694,18 +661,6 @@ #define ADCBS_BUFSIZE_57344 0x0000001e #define ADCBS_BUFSIZE_65536 0x0000001f -/* Current Send B, A Amounts */ -#define A_CSBA 0x4c - -/* Current Send D, C Amounts */ -#define A_CSDC 0x4d - -/* Current Send F, E Amounts */ -#define A_CSFE 0x4e - -/* Current Send H, G Amounts */ -#define A_CSHG 0x4f - #define CDCS 0x50 /* CD-ROM digital channel status register */ @@ -713,9 +668,6 @@ #define DBG 0x52 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */ -/* S/PDIF Input C Channel Status */ -#define A_SPSC 0x52 - #define REG53 0x53 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */ #define A_DBG 0x53 @@ -756,8 +708,6 @@ #define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */ #define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */ -/* 0x57: Not used */ - /* The 32-bit CLIx and SOLx registers all have one bit per channel control/status */ #define CLIEL 0x58 /* Channel loop interrupt enable low register */ @@ -783,9 +733,6 @@ #define AC97SLOT_CNTR 0x10 /* Center enable */ #define AC97SLOT_LFE 0x20 /* LFE enable */ -/* PCB Revision */ -#define A_PCB 0x5f - // NOTE: 0x60,61,62: 64-bit #define CDSRCS 0x60 /* CD-ROM Sample Rate Converter status register */ @@ -833,18 +780,9 @@ #define HLIPH 0x69 /* Channel half loop interrupt pending high register */ -/* S/PDIF Host Record Index (bypasses SRC) */ -#define A_SPRI 0x6a -/* S/PDIF Host Record Address */ -#define A_SPRA 0x6b -/* S/PDIF Host Record Control */ -#define A_SPRC 0x6c -/* Delayed Interrupt Counter & Enable */ -#define A_DICE 0x6d -/* Tank Table Base */ -#define A_TTB 0x6e -/* Tank Delay Offset */ -#define A_TDOF 0x6f +// 0x6a,6b,6c used for some recording +// 0x6d unused +// 0x6e,6f - tanktable base / offset /* This is the MPU port on the card (via the game port) */ #define A_MUDATA1 0x70 @@ -862,7 +800,6 @@ #define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */ #define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */ -/* Extended Hardware Control */ #define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */ #define A_SAMPLE_RATE 0x76 /* Various sample rate settings. */ #define A_SAMPLE_RATE_NOT_USED 0x0ffc111e /* Bits that are not used and cannot be set. */ @@ -885,20 +822,8 @@ #define A_PCM_96000 0x00004000 #define A_PCM_44100 0x00008000 -/* I2S0 Sample Rate Tracker Status */ -#define A_SRT3 0x77 - -/* I2S1 Sample Rate Tracker Status */ -#define A_SRT4 0x78 - -/* I2S2 Sample Rate Tracker Status */ -#define A_SRT5 0x79 -/* - default to 0x01080000 on my audigy 2 ZS --rlrevell */ - -/* Tank Table DMA Address */ -#define A_TTDA 0x7a -/* Tank Table DMA Data */ -#define A_TTDD 0x7b +/* 0x77,0x78,0x79 "something i2s-related" - default to 0x01080000 on my audigy 2 ZS --rlrevell */ +/* 0x7a, 0x7b - lookup tables */ #define A_FXRT2 0x7c #define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */ @@ -920,7 +845,7 @@ #define A_FXRT_CHANNELC 0x003f0000 #define A_FXRT_CHANNELD 0x3f000000 -/* 0x7f: Not used */ + /* Each FX general purpose register is 32 bits in length, all bits are used */ #define FXGPREGBASE 0x100 /* FX general purpose registers base */ #define A_FXGPREGBASE 0x400 /* Audigy GPRs, 0x400 to 0x5ff */ @@ -961,293 +886,6 @@ #define A_HIWORD_RESULT_MASK 0x007ff000 #define A_HIWORD_OPA_MASK 0x000007ff -/************************************************************************************************/ -/* EMU1010m HANA FPGA registers */ -/************************************************************************************************/ -#define EMU_HANA_DESTHI 0x00 /* 0000xxx 3 bits Link Destination */ -#define EMU_HANA_DESTLO 0x01 /* 00xxxxx 5 bits */ -#define EMU_HANA_SRCHI 0x02 /* 0000xxx 3 bits Link Source */ -#define EMU_HANA_SRCLO 0x03 /* 00xxxxx 5 bits */ -#define EMU_HANA_DOCK_PWR 0x04 /* 000000x 1 bits Audio Dock power */ -#define EMU_HANA_DOCK_PWR_ON 0x01 /* Audio Dock power on */ -#define EMU_HANA_WCLOCK 0x05 /* 0000xxx 3 bits Word Clock source select */ - /* Must be written after power on to reset DLL */ - /* One is unable to detect the Audio dock without this */ -#define EMU_HANA_WCLOCK_SRC_MASK 0x07 -#define EMU_HANA_WCLOCK_INT_48K 0x00 -#define EMU_HANA_WCLOCK_INT_44_1K 0x01 -#define EMU_HANA_WCLOCK_HANA_SPDIF_IN 0x02 -#define EMU_HANA_WCLOCK_HANA_ADAT_IN 0x03 -#define EMU_HANA_WCLOCK_SYNC_BNCN 0x04 -#define EMU_HANA_WCLOCK_2ND_HANA 0x05 -#define EMU_HANA_WCLOCK_SRC_RESERVED 0x06 -#define EMU_HANA_WCLOCK_OFF 0x07 /* For testing, forces fallback to DEFCLOCK */ -#define EMU_HANA_WCLOCK_MULT_MASK 0x18 -#define EMU_HANA_WCLOCK_1X 0x00 -#define EMU_HANA_WCLOCK_2X 0x08 -#define EMU_HANA_WCLOCK_4X 0x10 -#define EMU_HANA_WCLOCK_MULT_RESERVED 0x18 - -#define EMU_HANA_DEFCLOCK 0x06 /* 000000x 1 bits Default Word Clock */ -#define EMU_HANA_DEFCLOCK_48K 0x00 -#define EMU_HANA_DEFCLOCK_44_1K 0x01 - -#define EMU_HANA_UNMUTE 0x07 /* 000000x 1 bits Mute all audio outputs */ -#define EMU_MUTE 0x00 -#define EMU_UNMUTE 0x01 - -#define EMU_HANA_FPGA_CONFIG 0x08 /* 00000xx 2 bits Config control of FPGAs */ -#define EMU_HANA_FPGA_CONFIG_AUDIODOCK 0x01 /* Set in order to program FPGA on Audio Dock */ -#define EMU_HANA_FPGA_CONFIG_HANA 0x02 /* Set in order to program FPGA on Hana */ - -#define EMU_HANA_IRQ_ENABLE 0x09 /* 000xxxx 4 bits IRQ Enable */ -#define EMU_HANA_IRQ_WCLK_CHANGED 0x01 -#define EMU_HANA_IRQ_ADAT 0x02 -#define EMU_HANA_IRQ_DOCK 0x04 -#define EMU_HANA_IRQ_DOCK_LOST 0x08 - -#define EMU_HANA_SPDIF_MODE 0x0a /* 00xxxxx 5 bits SPDIF MODE */ -#define EMU_HANA_SPDIF_MODE_TX_COMSUMER 0x00 -#define EMU_HANA_SPDIF_MODE_TX_PRO 0x01 -#define EMU_HANA_SPDIF_MODE_TX_NOCOPY 0x02 -#define EMU_HANA_SPDIF_MODE_RX_COMSUMER 0x00 -#define EMU_HANA_SPDIF_MODE_RX_PRO 0x04 -#define EMU_HANA_SPDIF_MODE_RX_NOCOPY 0x08 -#define EMU_HANA_SPDIF_MODE_RX_INVALID 0x10 - -#define EMU_HANA_OPTICAL_TYPE 0x0b /* 00000xx 2 bits ADAT or SPDIF in/out */ -#define EMU_HANA_OPTICAL_IN_SPDIF 0x00 -#define EMU_HANA_OPTICAL_IN_ADAT 0x01 -#define EMU_HANA_OPTICAL_OUT_SPDIF 0x00 -#define EMU_HANA_OPTICAL_OUT_ADAT 0x02 - -#define EMU_HANA_MIDI_IN 0x0c /* 000000x 1 bit Control MIDI */ -#define EMU_HANA_MIDI_IN_FROM_HAMOA 0x00 /* HAMOA MIDI in to Alice 2 MIDI B */ -#define EMU_HANA_MIDI_IN_FROM_DOCK 0x01 /* Audio Dock MIDI in to Alice 2 MIDI B */ - -#define EMU_HANA_DOCK_LEDS_1 0x0d /* 000xxxx 4 bit Audio Dock LEDs */ -#define EMU_HANA_DOCK_LEDS_1_MIDI1 0x01 /* MIDI 1 LED on */ -#define EMU_HANA_DOCK_LEDS_1_MIDI2 0x02 /* MIDI 2 LED on */ -#define EMU_HANA_DOCK_LEDS_1_SMPTE_IN 0x04 /* SMPTE IN LED on */ -#define EMU_HANA_DOCK_LEDS_1_SMPTE_OUT 0x08 /* SMPTE OUT LED on */ - -#define EMU_HANA_DOCK_LEDS_2 0x0e /* 0xxxxxx 6 bit Audio Dock LEDs */ -#define EMU_HANA_DOCK_LEDS_2_44K 0x01 /* 44.1 kHz LED on */ -#define EMU_HANA_DOCK_LEDS_2_48K 0x02 /* 48 kHz LED on */ -#define EMU_HANA_DOCK_LEDS_2_96K 0x04 /* 96 kHz LED on */ -#define EMU_HANA_DOCK_LEDS_2_192K 0x08 /* 192 kHz LED on */ -#define EMU_HANA_DOCK_LEDS_2_LOCK 0x10 /* LOCK LED on */ -#define EMU_HANA_DOCK_LEDS_2_EXT 0x20 /* EXT LED on */ - -#define EMU_HANA_DOCK_LEDS_3 0x0f /* 0xxxxxx 6 bit Audio Dock LEDs */ -#define EMU_HANA_DOCK_LEDS_3_CLIP_A 0x01 /* Mic A Clip LED on */ -#define EMU_HANA_DOCK_LEDS_3_CLIP_B 0x02 /* Mic B Clip LED on */ -#define EMU_HANA_DOCK_LEDS_3_SIGNAL_A 0x04 /* Signal A Clip LED on */ -#define EMU_HANA_DOCK_LEDS_3_SIGNAL_B 0x08 /* Signal B Clip LED on */ -#define EMU_HANA_DOCK_LEDS_3_MANUAL_CLIP 0x10 /* Manual Clip detection */ -#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL 0x20 /* Manual Signal detection */ - -#define EMU_HANA_ADC_PADS 0x10 /* 0000xxx 3 bit Audio Dock ADC 14dB pads */ -#define EMU_HANA_DOCK_ADC_PAD1 0x01 /* 14dB Attenuation on Audio Dock ADC 1 */ -#define EMU_HANA_DOCK_ADC_PAD2 0x02 /* 14dB Attenuation on Audio Dock ADC 2 */ -#define EMU_HANA_DOCK_ADC_PAD3 0x04 /* 14dB Attenuation on Audio Dock ADC 3 */ -#define EMU_HANA_0202_ADC_PAD1 0x08 /* 14dB Attenuation on 0202 ADC 1 */ - -#define EMU_HANA_DOCK_MISC 0x11 /* 0xxxxxx 6 bit Audio Dock misc bits */ -#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */ -#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */ -#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */ -#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */ -#define EMU_HANA_DOCK_PHONES_192_DAC1 0x00 /* DAC 1 Headphones source at 192kHz */ -#define EMU_HANA_DOCK_PHONES_192_DAC2 0x10 /* DAC 2 Headphones source at 192kHz */ -#define EMU_HANA_DOCK_PHONES_192_DAC3 0x20 /* DAC 3 Headphones source at 192kHz */ -#define EMU_HANA_DOCK_PHONES_192_DAC4 0x30 /* DAC 4 Headphones source at 192kHz */ - -#define EMU_HANA_MIDI_OUT 0x12 /* 00xxxxx 5 bit Source for each MIDI out port */ -#define EMU_HANA_MIDI_OUT_0202 0x01 /* 0202 MIDI from Alice 2. 0 = A, 1 = B */ -#define EMU_HANA_MIDI_OUT_DOCK1 0x02 /* Audio Dock MIDI1 front, from Alice 2. 0 = A, 1 = B */ -#define EMU_HANA_MIDI_OUT_DOCK2 0x04 /* Audio Dock MIDI2 rear, from Alice 2. 0 = A, 1 = B */ -#define EMU_HANA_MIDI_OUT_SYNC2 0x08 /* Sync card. Not the actual MIDI out jack. 0 = A, 1 = B */ -#define EMU_HANA_MIDI_OUT_LOOP 0x10 /* 0 = bits (3:0) normal. 1 = MIDI loopback enabled. */ - -#define EMU_HANA_DAC_PADS 0x13 /* 00xxxxx 5 bit DAC 14dB attenuation pads */ -#define EMU_HANA_DOCK_DAC_PAD1 0x01 /* 14dB Attenuation on AudioDock DAC 1. Left and Right */ -#define EMU_HANA_DOCK_DAC_PAD2 0x02 /* 14dB Attenuation on AudioDock DAC 2. Left and Right */ -#define EMU_HANA_DOCK_DAC_PAD3 0x04 /* 14dB Attenuation on AudioDock DAC 3. Left and Right */ -#define EMU_HANA_DOCK_DAC_PAD4 0x08 /* 14dB Attenuation on AudioDock DAC 4. Left and Right */ -#define EMU_HANA_0202_DAC_PAD1 0x10 /* 14dB Attenuation on 0202 DAC 1. Left and Right */ - -/* 0x14 - 0x1f Unused R/W registers */ -#define EMU_HANA_IRQ_STATUS 0x20 /* 000xxxx 4 bits IRQ Status */ -#if 0 /* Already defined for reg 0x09 IRQ_ENABLE */ -#define EMU_HANA_IRQ_WCLK_CHANGED 0x01 -#define EMU_HANA_IRQ_ADAT 0x02 -#define EMU_HANA_IRQ_DOCK 0x04 -#define EMU_HANA_IRQ_DOCK_LOST 0x08 -#endif - -#define EMU_HANA_OPTION_CARDS 0x21 /* 000xxxx 4 bits Presence of option cards */ -#define EMU_HANA_OPTION_HAMOA 0x01 /* HAMOA card present */ -#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */ -#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio Dock online and FPGA configured */ -#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio Dock online and FPGA not configured */ - -#define EMU_HANA_ID 0x22 /* 1010101 7 bits ID byte & 0x7f = 0x55 */ - -#define EMU_HANA_MAJOR_REV 0x23 /* 0000xxx 3 bit Hana FPGA Major rev */ -#define EMU_HANA_MINOR_REV 0x24 /* 0000xxx 3 bit Hana FPGA Minor rev */ - -#define EMU_DOCK_MAJOR_REV 0x25 /* 0000xxx 3 bit Audio Dock FPGA Major rev */ -#define EMU_DOCK_MINOR_REV 0x26 /* 0000xxx 3 bit Audio Dock FPGA Minor rev */ - -#define EMU_DOCK_BOARD_ID 0x27 /* 00000xx 2 bits Audio Dock ID pins */ -#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */ -#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */ - -#define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */ -#define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */ - -#define EMU_HANA_WC_ADAT_HI 0x2a /* 0xxxxxx 6 bit ADAT IN Word clock, upper 6 bits */ -#define EMU_HANA_WC_ADAT_LO 0x2b /* 0xxxxxx 6 bit ADAT IN Word clock, lower 6 bits */ - -#define EMU_HANA_WC_BNC_LO 0x2c /* 0xxxxxx 6 bit BNC IN Word clock, lower 6 bits */ -#define EMU_HANA_WC_BNC_HI 0x2d /* 0xxxxxx 6 bit BNC IN Word clock, upper 6 bits */ - -#define EMU_HANA2_WC_SPDIF_HI 0x2e /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, upper 6 bits */ -#define EMU_HANA2_WC_SPDIF_LO 0x2f /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, lower 6 bits */ -/* 0x30 - 0x3f Unused Read only registers */ - -/************************************************************************************************/ -/* EMU1010m HANA Destinations */ -/************************************************************************************************/ -#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_3 0x0002 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_4 0x0003 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_5 0x0004 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_6 0x0005 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_7 0x0006 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_8 0x0007 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_9 0x0008 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_A 0x0009 /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_B 0x000a /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_C 0x000b /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_D 0x000c /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_E 0x000d /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_ALICE2_EMU32_F 0x000e /* 16 EMU32 channels to Alice2 +0 to +0xf */ -#define EMU_DST_DOCK_DAC1_LEFT1 0x0100 /* Audio Dock DAC1 Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC1_LEFT2 0x0101 /* Audio Dock DAC1 Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC1_LEFT3 0x0102 /* Audio Dock DAC1 Left, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC1_LEFT4 0x0103 /* Audio Dock DAC1 Left, 4th or 192kHz */ -#define EMU_DST_DOCK_DAC1_RIGHT1 0x0104 /* Audio Dock DAC1 Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC1_RIGHT2 0x0105 /* Audio Dock DAC1 Right, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC1_RIGHT3 0x0106 /* Audio Dock DAC1 Right, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC1_RIGHT4 0x0107 /* Audio Dock DAC1 Right, 4th or 192kHz */ -#define EMU_DST_DOCK_DAC2_LEFT1 0x0108 /* Audio Dock DAC2 Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC2_LEFT2 0x0109 /* Audio Dock DAC2 Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC2_LEFT3 0x010a /* Audio Dock DAC2 Left, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC2_LEFT4 0x010b /* Audio Dock DAC2 Left, 4th or 192kHz */ -#define EMU_DST_DOCK_DAC2_RIGHT1 0x010c /* Audio Dock DAC2 Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC2_RIGHT2 0x010d /* Audio Dock DAC2 Right, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC2_RIGHT3 0x010e /* Audio Dock DAC2 Right, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC2_RIGHT4 0x010f /* Audio Dock DAC2 Right, 4th or 192kHz */ -#define EMU_DST_DOCK_DAC3_LEFT1 0x0110 /* Audio Dock DAC1 Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC3_LEFT2 0x0111 /* Audio Dock DAC1 Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC3_LEFT3 0x0112 /* Audio Dock DAC1 Left, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC3_LEFT4 0x0113 /* Audio Dock DAC1 Left, 4th or 192kHz */ -#define EMU_DST_DOCK_PHONES_LEFT1 0x0112 /* Audio Dock PHONES Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_PHONES_LEFT2 0x0113 /* Audio Dock PHONES Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC3_RIGHT1 0x0114 /* Audio Dock DAC1 Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC3_RIGHT2 0x0115 /* Audio Dock DAC1 Right, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC3_RIGHT3 0x0116 /* Audio Dock DAC1 Right, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC3_RIGHT4 0x0117 /* Audio Dock DAC1 Right, 4th or 192kHz */ -#define EMU_DST_DOCK_PHONES_RIGHT1 0x0116 /* Audio Dock PHONES Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_PHONES_RIGHT2 0x0117 /* Audio Dock PHONES Right, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC4_LEFT1 0x0118 /* Audio Dock DAC2 Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC4_LEFT2 0x0119 /* Audio Dock DAC2 Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC4_LEFT3 0x011a /* Audio Dock DAC2 Left, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC4_LEFT4 0x011b /* Audio Dock DAC2 Left, 4th or 192kHz */ -#define EMU_DST_DOCK_SPDIF_LEFT1 0x011a /* Audio Dock SPDIF Left, 1st or 48kHz only */ -#define EMU_DST_DOCK_SPDIF_LEFT2 0x011b /* Audio Dock SPDIF Left, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC4_RIGHT1 0x011c /* Audio Dock DAC2 Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_DAC4_RIGHT2 0x011d /* Audio Dock DAC2 Right, 2nd or 96kHz */ -#define EMU_DST_DOCK_DAC4_RIGHT3 0x011e /* Audio Dock DAC2 Right, 3rd or 192kHz */ -#define EMU_DST_DOCK_DAC4_RIGHT4 0x011f /* Audio Dock DAC2 Right, 4th or 192kHz */ -#define EMU_DST_DOCK_SPDIF_RIGHT1 0x011e /* Audio Dock SPDIF Right, 1st or 48kHz only */ -#define EMU_DST_DOCK_SPDIF_RIGHT2 0x011f /* Audio Dock SPDIF Right, 2nd or 96kHz */ -#define EMU_DST_HANA_SPDIF_LEFT1 0x0200 /* Hana SPDIF Left, 1st or 48kHz only */ -#define EMU_DST_HANA_SPDIF_LEFT2 0x0202 /* Hana SPDIF Left, 2nd or 96kHz */ -#define EMU_DST_HANA_SPDIF_RIGHT1 0x0201 /* Hana SPDIF Right, 1st or 48kHz only */ -#define EMU_DST_HANA_SPDIF_RIGHT2 0x0203 /* Hana SPDIF Right, 2nd or 96kHz */ -#define EMU_DST_HAMOA_DAC_LEFT1 0x0300 /* Hamoa DAC Left, 1st or 48kHz only */ -#define EMU_DST_HAMOA_DAC_LEFT2 0x0302 /* Hamoa DAC Left, 2nd or 96kHz */ -#define EMU_DST_HAMOA_DAC_LEFT3 0x0304 /* Hamoa DAC Left, 3rd or 192kHz */ -#define EMU_DST_HAMOA_DAC_LEFT4 0x0306 /* Hamoa DAC Left, 4th or 192kHz */ -#define EMU_DST_HAMOA_DAC_RIGHT1 0x0301 /* Hamoa DAC Right, 1st or 48kHz only */ -#define EMU_DST_HAMOA_DAC_RIGHT2 0x0303 /* Hamoa DAC Right, 2nd or 96kHz */ -#define EMU_DST_HAMOA_DAC_RIGHT3 0x0305 /* Hamoa DAC Right, 3rd or 192kHz */ -#define EMU_DST_HAMOA_DAC_RIGHT4 0x0307 /* Hamoa DAC Right, 4th or 192kHz */ -#define EMU_DST_HANA_ADAT 0x0400 /* Hana ADAT 8 channel out +0 to +7 */ -#define EMU_DST_ALICE_I2S0_LEFT 0x0500 /* Alice2 I2S0 Left */ -#define EMU_DST_ALICE_I2S0_RIGHT 0x0501 /* Alice2 I2S0 Right */ -#define EMU_DST_ALICE_I2S1_LEFT 0x0600 /* Alice2 I2S1 Left */ -#define EMU_DST_ALICE_I2S1_RIGHT 0x0601 /* Alice2 I2S1 Right */ -#define EMU_DST_ALICE_I2S2_LEFT 0x0700 /* Alice2 I2S2 Left */ -#define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */ - -/************************************************************************************************/ -/* EMU1010m HANA Sources */ -/************************************************************************************************/ -#define EMU_SRC_SILENCE 0x0000 /* Silence */ -#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ -#define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ -#define EMU_SRC_DOCK_MIC_A3 0x0102 /* Audio Dock Mic A, 3rd or 192kHz */ -#define EMU_SRC_DOCK_MIC_A4 0x0103 /* Audio Dock Mic A, 4th or 192kHz */ -#define EMU_SRC_DOCK_MIC_B1 0x0104 /* Audio Dock Mic B, 1st or 48kHz only */ -#define EMU_SRC_DOCK_MIC_B2 0x0105 /* Audio Dock Mic B, 2nd or 96kHz */ -#define EMU_SRC_DOCK_MIC_B3 0x0106 /* Audio Dock Mic B, 3rd or 192kHz */ -#define EMU_SRC_DOCK_MIC_B4 0x0107 /* Audio Dock Mic B, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC1_LEFT1 0x0108 /* Audio Dock ADC1 Left, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC1_LEFT2 0x0109 /* Audio Dock ADC1 Left, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC1_LEFT3 0x010a /* Audio Dock ADC1 Left, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC1_LEFT4 0x010b /* Audio Dock ADC1 Left, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC1_RIGHT1 0x010c /* Audio Dock ADC1 Right, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC1_RIGHT2 0x010d /* Audio Dock ADC1 Right, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC1_RIGHT3 0x010e /* Audio Dock ADC1 Right, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC1_RIGHT4 0x010f /* Audio Dock ADC1 Right, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC2_LEFT1 0x0110 /* Audio Dock ADC2 Left, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC2_LEFT2 0x0111 /* Audio Dock ADC2 Left, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC2_LEFT3 0x0112 /* Audio Dock ADC2 Left, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC2_LEFT4 0x0113 /* Audio Dock ADC2 Left, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC2_RIGHT1 0x0114 /* Audio Dock ADC2 Right, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC2_RIGHT2 0x0115 /* Audio Dock ADC2 Right, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC2_RIGHT3 0x0116 /* Audio Dock ADC2 Right, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC2_RIGHT4 0x0117 /* Audio Dock ADC2 Right, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC3_LEFT1 0x0118 /* Audio Dock ADC3 Left, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC3_LEFT2 0x0119 /* Audio Dock ADC3 Left, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC3_LEFT3 0x011a /* Audio Dock ADC3 Left, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC3_LEFT4 0x011b /* Audio Dock ADC3 Left, 4th or 192kHz */ -#define EMU_SRC_DOCK_ADC3_RIGHT1 0x011c /* Audio Dock ADC3 Right, 1st or 48kHz only */ -#define EMU_SRC_DOCK_ADC3_RIGHT2 0x011d /* Audio Dock ADC3 Right, 2nd or 96kHz */ -#define EMU_SRC_DOCK_ADC3_RIGHT3 0x011e /* Audio Dock ADC3 Right, 3rd or 192kHz */ -#define EMU_SRC_DOCK_ADC3_RIGHT4 0x011f /* Audio Dock ADC3 Right, 4th or 192kHz */ -#define EMU_SRC_HAMOA_ADC_LEFT1 0x0200 /* Hamoa ADC Left, 1st or 48kHz only */ -#define EMU_SRC_HAMOA_ADC_LEFT2 0x0202 /* Hamoa ADC Left, 2nd or 96kHz */ -#define EMU_SRC_HAMOA_ADC_LEFT3 0x0204 /* Hamoa ADC Left, 3rd or 192kHz */ -#define EMU_SRC_HAMOA_ADC_LEFT4 0x0206 /* Hamoa ADC Left, 4th or 192kHz */ -#define EMU_SRC_HAMOA_ADC_RIGHT1 0x0201 /* Hamoa ADC Right, 1st or 48kHz only */ -#define EMU_SRC_HAMOA_ADC_RIGHT2 0x0203 /* Hamoa ADC Right, 2nd or 96kHz */ -#define EMU_SRC_HAMOA_ADC_RIGHT3 0x0205 /* Hamoa ADC Right, 3rd or 192kHz */ -#define EMU_SRC_HAMOA_ADC_RIGHT4 0x0207 /* Hamoa ADC Right, 4th or 192kHz */ -#define EMU_SRC_ALICE_EMU32A 0x0300 /* Alice2 EMU32a 16 outputs. +0 to +0xf */ -#define EMU_SRC_ALICE_EMU32B 0x0310 /* Alice2 EMU32b 16 outputs. +0 to +0xf */ -#define EMU_SRC_HANA_ADAT 0x0400 /* Hana ADAT 8 channel in +0 to +7 */ -#define EMU_SRC_HANA_SPDIF_LEFT1 0x0500 /* Hana SPDIF Left, 1st or 48kHz only */ -#define EMU_SRC_HANA_SPDIF_LEFT2 0x0502 /* Hana SPDIF Left, 2nd or 96kHz */ -#define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */ -#define EMU_SRC_HANA_SPDIF_RIGHT2 0x0503 /* Hana SPDIF Right, 2nd or 96kHz */ -/* 0x600 and 0x700 no used */ /* ------------------- STRUCTURES -------------------- */ @@ -1425,7 +1063,7 @@ struct snd_emu_chip_details { unsigned char spdif_bug; /* Has Spdif phasing bug */ unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ unsigned char ecard; /* APS EEPROM */ - unsigned char emu1010; /* EMU 1010m card */ + unsigned char emu1212m; /* EMU 1212m card */ unsigned char spi_dac; /* SPI interface for DAC */ unsigned char i2c_adc; /* I2C interface for ADC */ unsigned char adc_1361t; /* Use Philips 1361T ADC */ @@ -1434,14 +1072,6 @@ struct snd_emu_chip_details { const char *id; /* for backward compatibility - can be NULL if not needed */ }; -struct snd_emu1010 { - unsigned int output_source[64]; - unsigned int input_source[64]; - unsigned int adc_pads; /* bit mask */ - unsigned int dac_pads; /* bit mask */ - unsigned int internal_clock; /* 44100 or 48000 */ -}; - struct snd_emu10k1 { int irq; @@ -1449,7 +1079,6 @@ struct snd_emu10k1 { unsigned int tos_link: 1, /* tos link detected */ rear_ac97: 1, /* rear channels are on AC'97 */ enable_ir: 1; - unsigned int support_tlv :1; /* Contains profile of card capabilities */ const struct snd_emu_chip_details *card_capabilities; unsigned int audigy; /* is Audigy? */ @@ -1475,8 +1104,6 @@ struct snd_emu10k1 { spinlock_t memblk_lock; unsigned int spdif_bits[3]; /* s/pdif out setup */ - unsigned int i2c_capture_source; - u8 i2c_capture_volume[4][2]; struct snd_emu10k1_fx8010 fx8010; /* FX8010 info */ int gpr_base; @@ -1505,7 +1132,6 @@ struct snd_emu10k1 { int p16v_device_offset; u32 p16v_capture_source; u32 p16v_capture_channel; - struct snd_emu1010 emu1010; struct snd_emu10k1_pcm_mixer pcm_mixer[32]; struct snd_emu10k1_pcm_mixer efx_pcm_mixer[NUM_EFX_PLAYBACK]; struct snd_kcontrol *ctl_send_routing; @@ -1582,10 +1208,6 @@ void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned i unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data); -int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value); -int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value); -int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value); -int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src); unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc); void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb); void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb); @@ -1902,20 +1524,11 @@ struct snd_emu10k1_fx8010_control_gpr { unsigned int value[32]; /* initial values */ unsigned int min; /* minimum range */ unsigned int max; /* maximum range */ + union { + snd_kcontrol_tlv_rw_t *c; + unsigned int *p; + } tlv; unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ - const unsigned int *tlv; -}; - -/* old ABI without TLV support */ -struct snd_emu10k1_fx8010_control_old_gpr { - struct snd_ctl_elem_id id; - unsigned int vcount; - unsigned int count; - unsigned short gpr[32]; - unsigned int value[32]; - unsigned int min; - unsigned int max; - unsigned int translation; }; struct snd_emu10k1_fx8010_code { @@ -1966,8 +1579,6 @@ struct snd_emu10k1_fx8010_pcm_rec { unsigned int res2; /* reserved */ }; -#define SNDRV_EMU10K1_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1) - #define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, struct snd_emu10k1_fx8010_info) #define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, struct snd_emu10k1_fx8010_code) #define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, struct snd_emu10k1_fx8010_code) @@ -1976,7 +1587,6 @@ struct snd_emu10k1_fx8010_pcm_rec { #define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, struct snd_emu10k1_fx8010_tram) #define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, struct snd_emu10k1_fx8010_pcm_rec) #define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, struct snd_emu10k1_fx8010_pcm_rec) -#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int) #define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80) #define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81) #define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82) diff --git a/trunk/include/sound/pcm.h b/trunk/include/sound/pcm.h index ee6bc2d06803..2f645dfd7f70 100644 --- a/trunk/include/sound/pcm.h +++ b/trunk/include/sound/pcm.h @@ -56,8 +56,6 @@ struct snd_pcm_hardware { size_t fifo_size; /* fifo size in bytes */ }; -struct snd_pcm_substream; - struct snd_pcm_ops { int (*open)(struct snd_pcm_substream *substream); int (*close)(struct snd_pcm_substream *substream); @@ -386,7 +384,6 @@ struct snd_pcm_substream { struct snd_info_entry *proc_sw_params_entry; struct snd_info_entry *proc_status_entry; struct snd_info_entry *proc_prealloc_entry; - struct snd_info_entry *proc_prealloc_max_entry; #endif /* misc flags */ unsigned int hw_opened: 1; @@ -430,7 +427,6 @@ struct snd_pcm { wait_queue_head_t open_wait; void *private_data; void (*private_free) (struct snd_pcm *pcm); - struct device *dev; /* actual hw device this belongs to */ #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) struct snd_pcm_oss oss; #endif diff --git a/trunk/include/sound/pt2258.h b/trunk/include/sound/pt2258.h deleted file mode 100644 index 160f812faa42..000000000000 --- a/trunk/include/sound/pt2258.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ALSA Driver for the PT2258 volume controller. - * - * Copyright (c) 2006 Jochen Voss - * - * 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 - * - */ - -#ifndef __SOUND_PT2258_H -#define __SOUND_PT2258_H - -struct snd_pt2258 { - struct snd_card *card; - struct snd_i2c_bus *i2c_bus; - struct snd_i2c_device *i2c_dev; - - unsigned char volume[6]; - int mute; -}; - -extern int snd_pt2258_reset(struct snd_pt2258 *pt); -extern int snd_pt2258_build_controls(struct snd_pt2258 *pt); - -#endif /* __SOUND_PT2258_H */ diff --git a/trunk/include/sound/sb16_csp.h b/trunk/include/sound/sb16_csp.h index 736eac71d053..caf6fe21514d 100644 --- a/trunk/include/sound/sb16_csp.h +++ b/trunk/include/sound/sb16_csp.h @@ -114,21 +114,9 @@ struct snd_sb_csp_info { #ifdef __KERNEL__ #include "sb.h" #include "hwdep.h" -#include struct snd_sb_csp; -/* indices for the known CSP programs */ -enum { - CSP_PROGRAM_MULAW, - CSP_PROGRAM_ALAW, - CSP_PROGRAM_ADPCM_INIT, - CSP_PROGRAM_ADPCM_PLAYBACK, - CSP_PROGRAM_ADPCM_CAPTURE, - - CSP_PROGRAM_COUNT -}; - /* * CSP operators */ @@ -171,8 +159,6 @@ struct snd_sb_csp { struct snd_kcontrol *qsound_space; struct mutex access_mutex; /* locking */ - - const struct firmware *csp_programs[CSP_PROGRAM_COUNT]; }; int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep); diff --git a/trunk/include/sound/snd_wavefront.h b/trunk/include/sound/snd_wavefront.h index 9688d4be918e..0b9e5de94ff1 100644 --- a/trunk/include/sound/snd_wavefront.h +++ b/trunk/include/sound/snd_wavefront.h @@ -85,7 +85,6 @@ struct _snd_wavefront { char hw_version[2]; /* major = [0], minor = [1] */ char israw; /* needs Motorola microcode */ char has_fx; /* has FX processor (Tropez+) */ - char fx_initialized; /* FX's register pages initialized */ char prog_status[WF_MAX_PROGRAM]; /* WF_SLOT_* */ char patch_status[WF_MAX_PATCH]; /* WF_SLOT_* */ char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */ @@ -95,7 +94,6 @@ struct _snd_wavefront { spinlock_t irq_lock; wait_queue_head_t interrupt_sleeper; snd_wavefront_midi_t midi; /* ICS2115 MIDI interface */ - struct snd_card *card; }; struct _snd_wavefront_card { diff --git a/trunk/include/sound/soc-dapm.h b/trunk/include/sound/soc-dapm.h deleted file mode 100644 index 2b1ae8edc43c..000000000000 --- a/trunk/include/sound/soc-dapm.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * linux/sound/soc-dapm.h -- ALSA SoC Dynamic Audio Power Management - * - * Author: Liam Girdwood - * Created: Aug 11th 2005 - * Copyright: Wolfson Microelectronics. PLC. - * - * 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 __LINUX_SND_SOC_DAPM_H -#define __LINUX_SND_SOC_DAPM_H - -#include -#include -#include -#include - -/* widget has no PM register bit */ -#define SND_SOC_NOPM -1 - -/* - * SoC dynamic audio power managment - * - * We can have upto 4 power domains - * 1. Codec domain - VREF, VMID - * Usually controlled at codec probe/remove, although can be set - * at stream time if power is not needed for sidetone, etc. - * 2. Platform/Machine domain - physically connected inputs and outputs - * Is platform/machine and user action specific, is set in the machine - * driver and by userspace e.g when HP are inserted - * 3. Path domain - Internal codec path mixers - * Are automatically set when mixer and mux settings are - * changed by the user. - * 4. Stream domain - DAC's and ADC's. - * Enabled when stream playback/capture is started. - */ - -/* codec domain */ -#define SND_SOC_DAPM_VMID(wname) \ -{ .id = snd_soc_dapm_vmid, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0} - -/* platform domain */ -#define SND_SOC_DAPM_INPUT(wname) \ -{ .id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0} -#define SND_SOC_DAPM_OUTPUT(wname) \ -{ .id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0} -#define SND_SOC_DAPM_MIC(wname, wevent) \ -{ .id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} -#define SND_SOC_DAPM_HP(wname, wevent) \ -{ .id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} -#define SND_SOC_DAPM_SPK(wname, wevent) \ -{ .id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} -#define SND_SOC_DAPM_LINE(wname, wevent) \ -{ .id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} - -/* path domain */ -#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\ - wcontrols, wncontrols) \ -{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} -#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \ - wcontrols, wncontrols)\ -{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} -#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \ -{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0} -#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \ -{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} -#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \ -{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} - -/* path domain with event - event handler must return 0 for success */ -#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \ - wncontrols, wevent, wflags) \ -{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ - .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \ - wncontrols, wevent, wflags) \ -{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ - .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_MICBIAS_E(wname, wreg, wshift, winvert, wevent, wflags) \ -{ .id = snd_soc_dapm_micbias, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0, \ - .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \ - wevent, wflags) \ -{ .id = snd_soc_dapm_switch, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1 \ - .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ - wevent, wflags) \ -{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ - .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ - .event = wevent, .event_flags = wflags} - -/* events that are pre and post DAPM */ -#define SND_SOC_DAPM_PRE(wname, wevent) \ -{ .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD} -#define SND_SOC_DAPM_POST(wname, wevent) \ -{ .id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ - .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} - -/* stream domain */ -#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \ -{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ - .shift = wshift, .invert = winvert} -#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \ -{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ - .shift = wshift, .invert = winvert} - -/* dapm kcontrol types */ -#define SOC_DAPM_SINGLE(xname, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) } -#define SOC_DAPM_DOUBLE(xname, reg, shift_left, shift_right, mask, invert, \ - power) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\ - ((mask) << 16) | ((invert) << 24) } -#define SOC_DAPM_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_enum_double, \ - .get = snd_soc_dapm_get_enum_double, \ - .put = snd_soc_dapm_put_enum_double, \ - .private_value = (unsigned long)&xenum } - -/* dapm stream operations */ -#define SND_SOC_DAPM_STREAM_NOP 0x0 -#define SND_SOC_DAPM_STREAM_START 0x1 -#define SND_SOC_DAPM_STREAM_STOP 0x2 -#define SND_SOC_DAPM_STREAM_SUSPEND 0x4 -#define SND_SOC_DAPM_STREAM_RESUME 0x8 -#define SND_SOC_DAPM_STREAM_PAUSE_PUSH 0x10 -#define SND_SOC_DAPM_STREAM_PAUSE_RELEASE 0x20 - -/* dapm event types */ -#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ -#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ -#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ -#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ -#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ -#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ - -/* convenience event type detection */ -#define SND_SOC_DAPM_EVENT_ON(e) \ - (e & (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)) -#define SND_SOC_DAPM_EVENT_OFF(e) \ - (e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)) - -struct snd_soc_dapm_widget; -enum snd_soc_dapm_type; -struct snd_soc_dapm_path; -struct snd_soc_dapm_pin; - -/* dapm controls */ -int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, - const struct snd_soc_dapm_widget *widget); - -/* dapm path setup */ -int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, - const char *sink_name, const char *control_name, const char *src_name); -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); -void snd_soc_dapm_free(struct snd_soc_device *socdev); - -/* dapm events */ -int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, - int event); - -/* dapm sys fs - used by the core */ -int snd_soc_dapm_sys_add(struct device *dev); - -/* dapm audio endpoint control */ -int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, - char *pin, int status); -int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec); - -/* dapm widget types */ -enum snd_soc_dapm_type { - snd_soc_dapm_input = 0, /* input pin */ - snd_soc_dapm_output, /* output pin */ - snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ - snd_soc_dapm_mixer, /* mixes several analog signals together */ - snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ - snd_soc_dapm_adc, /* analog to digital converter */ - snd_soc_dapm_dac, /* digital to analog converter */ - snd_soc_dapm_micbias, /* microphone bias (power) */ - snd_soc_dapm_mic, /* microphone */ - snd_soc_dapm_hp, /* headphones */ - snd_soc_dapm_spk, /* speaker */ - snd_soc_dapm_line, /* line input/output */ - snd_soc_dapm_switch, /* analog switch */ - snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */ - snd_soc_dapm_pre, /* machine specific pre widget - exec first */ - snd_soc_dapm_post, /* machine specific post widget - exec last */ -}; - -/* dapm audio path between two widgets */ -struct snd_soc_dapm_path { - char *name; - char *long_name; - - /* source (input) and sink (output) widgets */ - struct snd_soc_dapm_widget *source; - struct snd_soc_dapm_widget *sink; - struct snd_kcontrol *kcontrol; - - /* status */ - u32 connect:1; /* source and sink widgets are connected */ - u32 walked:1; /* path has been walked */ - - struct list_head list_source; - struct list_head list_sink; - struct list_head list; -}; - -/* dapm widget */ -struct snd_soc_dapm_widget { - enum snd_soc_dapm_type id; - char *name; /* widget name */ - char *sname; /* stream name */ - struct snd_soc_codec *codec; - struct list_head list; - - /* dapm control */ - short reg; /* negative reg = no direct dapm */ - unsigned char shift; /* bits to shift */ - unsigned int saved_value; /* widget saved value */ - unsigned int value; /* widget current value */ - unsigned char power:1; /* block power status */ - unsigned char invert:1; /* invert the power bit */ - unsigned char active:1; /* active stream on DAC, ADC's */ - unsigned char connected:1; /* connected codec pin */ - unsigned char new:1; /* cnew complete */ - unsigned char ext:1; /* has external widgets */ - unsigned char muted:1; /* muted for pop reduction */ - unsigned char suspend:1; /* was active before suspend */ - unsigned char pmdown:1; /* waiting for timeout */ - - /* external events */ - unsigned short event_flags; /* flags to specify event types */ - int (*event)(struct snd_soc_dapm_widget*, int); - - /* kcontrols that relate to this widget */ - int num_kcontrols; - const struct snd_kcontrol_new *kcontrols; - - /* widget input and outputs */ - struct list_head sources; - struct list_head sinks; -}; - -#endif diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h deleted file mode 100644 index b1dc364b8f74..000000000000 --- a/trunk/include/sound/soc.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - * linux/sound/soc.h -- ALSA SoC Layer - * - * Author: Liam Girdwood - * Created: Aug 11th 2005 - * Copyright: Wolfson Microelectronics. PLC. - * - * 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 __LINUX_SND_SOC_H -#define __LINUX_SND_SOC_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SND_SOC_VERSION "0.13.0" - -/* - * Convenience kcontrol builders - */ -#define SOC_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) |\ - ((shift) << 12) | ((mask) << 16) | ((invert) << 24)) -#define SOC_SINGLE_VALUE_EXT(reg,mask,invert) ((reg) | ((mask) << 16) |\ - ((invert) << 31)) -#define SOC_SINGLE(xname, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ - .put = snd_soc_put_volsw, \ - .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) } -#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ - .put = snd_soc_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | \ - ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } -#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw_2r, \ - .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ - .private_value = (reg_left) | ((shift) << 8) | \ - ((mask) << 12) | ((invert) << 20) | ((reg_right) << 24) } -#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ -{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ - .mask = xmask, .texts = xtexts } -#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ - SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) -#define SOC_ENUM_SINGLE_EXT(xmask, xtexts) \ -{ .mask = xmask, .texts = xtexts } -#define SOC_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\ - .info = snd_soc_info_enum_double, \ - .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ - .private_value = (unsigned long)&xenum } -#define SOC_SINGLE_EXT(xname, xreg, xshift, xmask, xinvert,\ - xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_volsw, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmask, xinvert) } -#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_bool_ext, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = xdata } -#define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .info = snd_soc_info_enum_ext, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = (unsigned long)&xenum } - -/* - * Digital Audio Interface (DAI) types - */ -#define SND_SOC_DAI_AC97 0x1 -#define SND_SOC_DAI_I2S 0x2 -#define SND_SOC_DAI_PCM 0x4 - -/* - * DAI hardware audio formats - */ -#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ -#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right justified mode */ -#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ -#define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM or LRC */ -#define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM or LRC */ -#define SND_SOC_DAIFMT_AC97 5 /* AC97 */ - -#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J -#define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J - -/* - * DAI Gating - */ -#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ -#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated when not Tx/Rx */ - -/* - * DAI hardware signal inversions - */ -#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ -#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */ -#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */ -#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */ - -/* - * DAI hardware clock masters - * This is wrt the codec, the inverse is true for the interface - * i.e. if the codec is clk and frm master then the interface is - * clk and frame slave. - */ -#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */ -#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */ -#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ -#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */ - -#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f -#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 -#define SND_SOC_DAIFMT_INV_MASK 0x0f00 -#define SND_SOC_DAIFMT_MASTER_MASK 0xf000 - - -/* - * Master Clock Directions - */ -#define SND_SOC_CLOCK_IN 0 -#define SND_SOC_CLOCK_OUT 1 - -/* - * AC97 codec ID's bitmask - */ -#define SND_SOC_DAI_AC97_ID0 (1 << 0) -#define SND_SOC_DAI_AC97_ID1 (1 << 1) -#define SND_SOC_DAI_AC97_ID2 (1 << 2) -#define SND_SOC_DAI_AC97_ID3 (1 << 3) - -struct snd_soc_device; -struct snd_soc_pcm_stream; -struct snd_soc_ops; -struct snd_soc_dai_mode; -struct snd_soc_pcm_runtime; -struct snd_soc_codec_dai; -struct snd_soc_cpu_dai; -struct snd_soc_codec; -struct snd_soc_machine_config; -struct soc_enum; -struct snd_soc_ac97_ops; -struct snd_soc_clock_info; - -typedef int (*hw_write_t)(void *,const char* ,int); -typedef int (*hw_read_t)(void *,char* ,int); - -extern struct snd_ac97_bus_ops soc_ac97_ops; - -/* pcm <-> DAI connect */ -void snd_soc_free_pcms(struct snd_soc_device *socdev); -int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid); -int snd_soc_register_card(struct snd_soc_device *socdev); - -/* set runtime hw params */ -int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, - const struct snd_pcm_hardware *hw); - -/* codec IO */ -#define snd_soc_read(codec, reg) codec->read(codec, reg) -#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value) - -/* codec register bit access */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned short mask, unsigned short value); -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned short mask, unsigned short value); - -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, - struct snd_ac97_bus_ops *ops, int num); -void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); - -/* - *Controls - */ -struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, - void *data, char *long_name); -int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_info_bool_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo); -int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); - -/* SoC PCM stream information */ -struct snd_soc_pcm_stream { - char *stream_name; - u64 formats; /* SNDRV_PCM_FMTBIT_* */ - unsigned int rates; /* SNDRV_PCM_RATE_* */ - unsigned int rate_min; /* min rate */ - unsigned int rate_max; /* max rate */ - unsigned int channels_min; /* min channels */ - unsigned int channels_max; /* max channels */ - unsigned int active:1; /* stream is in use */ -}; - -/* SoC audio ops */ -struct snd_soc_ops { - int (*startup)(struct snd_pcm_substream *); - void (*shutdown)(struct snd_pcm_substream *); - int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); - int (*hw_free)(struct snd_pcm_substream *); - int (*prepare)(struct snd_pcm_substream *); - int (*trigger)(struct snd_pcm_substream *, int); -}; - -/* ASoC codec DAI ops */ -struct snd_soc_codec_ops { - /* codec DAI clocking configuration */ - int (*set_sysclk)(struct snd_soc_codec_dai *codec_dai, - int clk_id, unsigned int freq, int dir); - int (*set_pll)(struct snd_soc_codec_dai *codec_dai, - int pll_id, unsigned int freq_in, unsigned int freq_out); - int (*set_clkdiv)(struct snd_soc_codec_dai *codec_dai, - int div_id, int div); - - /* CPU DAI format configuration */ - int (*set_fmt)(struct snd_soc_codec_dai *codec_dai, - unsigned int fmt); - int (*set_tdm_slot)(struct snd_soc_codec_dai *codec_dai, - unsigned int mask, int slots); - int (*set_tristate)(struct snd_soc_codec_dai *, int tristate); - - /* digital mute */ - int (*digital_mute)(struct snd_soc_codec_dai *, int mute); -}; - -/* ASoC cpu DAI ops */ -struct snd_soc_cpu_ops { - /* CPU DAI clocking configuration */ - int (*set_sysclk)(struct snd_soc_cpu_dai *cpu_dai, - int clk_id, unsigned int freq, int dir); - int (*set_clkdiv)(struct snd_soc_cpu_dai *cpu_dai, - int div_id, int div); - int (*set_pll)(struct snd_soc_cpu_dai *cpu_dai, - int pll_id, unsigned int freq_in, unsigned int freq_out); - - /* CPU DAI format configuration */ - int (*set_fmt)(struct snd_soc_cpu_dai *cpu_dai, - unsigned int fmt); - int (*set_tdm_slot)(struct snd_soc_cpu_dai *cpu_dai, - unsigned int mask, int slots); - int (*set_tristate)(struct snd_soc_cpu_dai *, int tristate); -}; - -/* SoC Codec DAI */ -struct snd_soc_codec_dai { - char *name; - int id; - - /* DAI capabilities */ - struct snd_soc_pcm_stream playback; - struct snd_soc_pcm_stream capture; - - /* DAI runtime info */ - struct snd_soc_codec *codec; - unsigned int active; - unsigned char pop_wait:1; - - /* ops */ - struct snd_soc_ops ops; - struct snd_soc_codec_ops dai_ops; - - /* DAI private data */ - void *private_data; -}; - -/* SoC CPU DAI */ -struct snd_soc_cpu_dai { - - /* DAI description */ - char *name; - unsigned int id; - unsigned char type; - - /* DAI callbacks */ - int (*probe)(struct platform_device *pdev); - void (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); - int (*resume)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); - - /* ops */ - struct snd_soc_ops ops; - struct snd_soc_cpu_ops dai_ops; - - /* DAI capabilities */ - struct snd_soc_pcm_stream capture; - struct snd_soc_pcm_stream playback; - - /* DAI runtime info */ - struct snd_pcm_runtime *runtime; - unsigned char active:1; - void *dma_data; - - /* DAI private data */ - void *private_data; -}; - -/* SoC Audio Codec */ -struct snd_soc_codec { - char *name; - struct module *owner; - struct mutex mutex; - - /* callbacks */ - int (*dapm_event)(struct snd_soc_codec *codec, int event); - - /* runtime */ - struct snd_card *card; - struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ - unsigned int active; - unsigned int pcm_devs; - void *private_data; - - /* codec IO */ - void *control_data; /* codec control (i2c/3wire) data */ - unsigned int (*read)(struct snd_soc_codec *, unsigned int); - int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - hw_write_t hw_write; - hw_read_t hw_read; - void *reg_cache; - short reg_cache_size; - short reg_cache_step; - - /* dapm */ - struct list_head dapm_widgets; - struct list_head dapm_paths; - unsigned int dapm_state; - unsigned int suspend_dapm_state; - struct delayed_work delayed_work; - - /* codec DAI's */ - struct snd_soc_codec_dai *dai; - unsigned int num_dai; -}; - -/* codec device */ -struct snd_soc_codec_device { - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, pm_message_t state); - int (*resume)(struct platform_device *pdev); -}; - -/* SoC platform interface */ -struct snd_soc_platform { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - int (*suspend)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); - int (*resume)(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai); - - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, - struct snd_pcm *); - void (*pcm_free)(struct snd_pcm *); - - /* platform stream ops */ - struct snd_pcm_ops *pcm_ops; -}; - -/* SoC machine DAI configuration, glues a codec and cpu DAI together */ -struct snd_soc_dai_link { - char *name; /* Codec name */ - char *stream_name; /* Stream name */ - - /* DAI */ - struct snd_soc_codec_dai *codec_dai; - struct snd_soc_cpu_dai *cpu_dai; - - /* machine stream operations */ - struct snd_soc_ops *ops; - - /* codec/machine specific init - e.g. add machine controls */ - int (*init)(struct snd_soc_codec *codec); -}; - -/* SoC machine */ -struct snd_soc_machine { - char *name; - - int (*probe)(struct platform_device *pdev); - int (*remove)(struct platform_device *pdev); - - /* the pre and post PM functions are used to do any PM work before and - * after the codec and DAI's do any PM work. */ - int (*suspend_pre)(struct platform_device *pdev, pm_message_t state); - int (*suspend_post)(struct platform_device *pdev, pm_message_t state); - int (*resume_pre)(struct platform_device *pdev); - int (*resume_post)(struct platform_device *pdev); - - /* CPU <--> Codec DAI links */ - struct snd_soc_dai_link *dai_link; - int num_links; -}; - -/* SoC Device - the audio subsystem */ -struct snd_soc_device { - struct device *dev; - struct snd_soc_machine *machine; - struct snd_soc_platform *platform; - struct snd_soc_codec *codec; - struct snd_soc_codec_device *codec_dev; - struct delayed_work delayed_work; - void *codec_data; -}; - -/* runtime channel data */ -struct snd_soc_pcm_runtime { - struct snd_soc_dai_link *dai; - struct snd_soc_device *socdev; -}; - -/* enumerated kcontrol */ -struct soc_enum { - unsigned short reg; - unsigned short reg2; - unsigned char shift_l; - unsigned char shift_r; - unsigned int mask; - const char **texts; - void *dapm; -}; - -#endif diff --git a/trunk/include/sound/typedefs.h b/trunk/include/sound/typedefs.h new file mode 100644 index 000000000000..f454b0206b93 --- /dev/null +++ b/trunk/include/sound/typedefs.h @@ -0,0 +1,173 @@ +/* + * Typedef's for backward compatibility (for out-of-kernel drivers) + * + * This file will be removed soon in future + */ + +/* core stuff */ +typedef struct snd_card snd_card_t; +typedef struct snd_device snd_device_t; +typedef struct snd_device_ops snd_device_ops_t; +typedef enum snd_card_type snd_card_type_t; +typedef struct snd_minor snd_minor_t; + +/* info */ +typedef struct snd_info_entry snd_info_entry_t; +typedef struct snd_info_buffer snd_info_buffer_t; + +/* control */ +typedef struct snd_ctl_file snd_ctl_file_t; +typedef struct snd_kcontrol snd_kcontrol_t; +typedef struct snd_kcontrol_new snd_kcontrol_new_t; +typedef struct snd_kcontrol_volatile snd_kcontrol_volatile_t; +typedef struct snd_kctl_event snd_kctl_event_t; +typedef struct snd_aes_iec958 snd_aes_iec958_t; +typedef struct snd_ctl_card_info snd_ctl_card_info_t; +typedef struct snd_ctl_elem_id snd_ctl_elem_id_t; +typedef struct snd_ctl_elem_list snd_ctl_elem_list_t; +typedef struct snd_ctl_elem_info snd_ctl_elem_info_t; +typedef struct snd_ctl_elem_value snd_ctl_elem_value_t; +typedef struct snd_ctl_event snd_ctl_event_t; +#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) +typedef struct snd_mixer_oss snd_mixer_oss_t; +#endif + +/* timer */ +typedef struct snd_timer snd_timer_t; +typedef struct snd_timer_instance snd_timer_instance_t; +typedef struct snd_timer_id snd_timer_id_t; +typedef struct snd_timer_ginfo snd_timer_ginfo_t; +typedef struct snd_timer_gparams snd_timer_gparams_t; +typedef struct snd_timer_gstatus snd_timer_gstatus_t; +typedef struct snd_timer_select snd_timer_select_t; +typedef struct snd_timer_info snd_timer_info_t; +typedef struct snd_timer_params snd_timer_params_t; +typedef struct snd_timer_status snd_timer_status_t; +typedef struct snd_timer_read snd_timer_read_t; +typedef struct snd_timer_tread snd_timer_tread_t; + +/* PCM */ +typedef struct snd_pcm snd_pcm_t; +typedef struct snd_pcm_str snd_pcm_str_t; +typedef struct snd_pcm_substream snd_pcm_substream_t; +typedef struct snd_pcm_info snd_pcm_info_t; +typedef struct snd_pcm_hw_params snd_pcm_hw_params_t; +typedef struct snd_pcm_sw_params snd_pcm_sw_params_t; +typedef struct snd_pcm_channel_info snd_pcm_channel_info_t; +typedef struct snd_pcm_status snd_pcm_status_t; +typedef struct snd_pcm_mmap_status snd_pcm_mmap_status_t; +typedef struct snd_pcm_mmap_control snd_pcm_mmap_control_t; +typedef struct snd_mask snd_mask_t; +typedef struct snd_sg_buf snd_pcm_sgbuf_t; + +typedef struct snd_interval snd_interval_t; +typedef struct snd_xferi snd_xferi_t; +typedef struct snd_xfern snd_xfern_t; +typedef struct snd_xferv snd_xferv_t; + +typedef struct snd_pcm_file snd_pcm_file_t; +typedef struct snd_pcm_runtime snd_pcm_runtime_t; +typedef struct snd_pcm_hardware snd_pcm_hardware_t; +typedef struct snd_pcm_ops snd_pcm_ops_t; +typedef struct snd_pcm_hw_rule snd_pcm_hw_rule_t; +typedef struct snd_pcm_hw_constraints snd_pcm_hw_constraints_t; +typedef struct snd_ratnum ratnum_t; +typedef struct snd_ratden ratden_t; +typedef struct snd_pcm_hw_constraint_ratnums snd_pcm_hw_constraint_ratnums_t; +typedef struct snd_pcm_hw_constraint_ratdens snd_pcm_hw_constraint_ratdens_t; +typedef struct snd_pcm_hw_constraint_list snd_pcm_hw_constraint_list_t; +typedef struct snd_pcm_group snd_pcm_group_t; +typedef struct snd_pcm_notify snd_pcm_notify_t; + +/* rawmidi */ +typedef struct snd_rawmidi snd_rawmidi_t; +typedef struct snd_rawmidi_info snd_rawmidi_info_t; +typedef struct snd_rawmidi_params snd_rawmidi_params_t; +typedef struct snd_rawmidi_status snd_rawmidi_status_t; +typedef struct snd_rawmidi_runtime snd_rawmidi_runtime_t; +typedef struct snd_rawmidi_substream snd_rawmidi_substream_t; +typedef struct snd_rawmidi_str snd_rawmidi_str_t; +typedef struct snd_rawmidi_ops snd_rawmidi_ops_t; +typedef struct snd_rawmidi_global_ops snd_rawmidi_global_ops_t; +typedef struct snd_rawmidi_file snd_rawmidi_file_t; + +/* hwdep */ +typedef struct snd_hwdep snd_hwdep_t; +typedef struct snd_hwdep_info snd_hwdep_info_t; +typedef struct snd_hwdep_dsp_status snd_hwdep_dsp_status_t; +typedef struct snd_hwdep_dsp_image snd_hwdep_dsp_image_t; +typedef struct snd_hwdep_ops snd_hwdep_ops_t; + +/* sequencer */ +typedef struct snd_seq_port_info snd_seq_port_info_t; +typedef struct snd_seq_port_subscribe snd_seq_port_subscribe_t; +typedef struct snd_seq_event snd_seq_event_t; +typedef struct snd_seq_addr snd_seq_addr_t; +typedef struct snd_seq_ev_volume snd_seq_ev_volume_t; +typedef struct snd_seq_ev_loop snd_seq_ev_loop_t; +typedef struct snd_seq_remove_events snd_seq_remove_events_t; +typedef struct snd_seq_query_subs snd_seq_query_subs_t; +typedef struct snd_seq_system_info snd_seq_system_info_t; +typedef struct snd_seq_client_info snd_seq_client_info_t; +typedef struct snd_seq_queue_info snd_seq_queue_info_t; +typedef struct snd_seq_queue_status snd_seq_queue_status_t; +typedef struct snd_seq_queue_tempo snd_seq_queue_tempo_t; +typedef struct snd_seq_queue_owner snd_seq_queue_owner_t; +typedef struct snd_seq_queue_timer snd_seq_queue_timer_t; +typedef struct snd_seq_queue_client snd_seq_queue_client_t; +typedef struct snd_seq_client_pool snd_seq_client_pool_t; +typedef struct snd_seq_instr snd_seq_instr_t; +typedef struct snd_seq_instr_data snd_seq_instr_data_t; +typedef struct snd_seq_instr_header snd_seq_instr_header_t; + +typedef struct snd_seq_user_client user_client_t; +typedef struct snd_seq_kernel_client kernel_client_t; +typedef struct snd_seq_client client_t; +typedef struct snd_seq_queue queue_t; + +/* seq_device */ +typedef struct snd_seq_device snd_seq_device_t; +typedef struct snd_seq_dev_ops snd_seq_dev_ops_t; + +/* seq_midi */ +typedef struct snd_midi_event snd_midi_event_t; + +/* seq_midi_emul */ +typedef struct snd_midi_channel snd_midi_channel_t; +typedef struct snd_midi_channel_set snd_midi_channel_set_t; +typedef struct snd_midi_op snd_midi_op_t; + +/* seq_oss */ +typedef struct snd_seq_oss_arg snd_seq_oss_arg_t; +typedef struct snd_seq_oss_callback snd_seq_oss_callback_t; +typedef struct snd_seq_oss_reg snd_seq_oss_reg_t; + +/* virmidi */ +typedef struct snd_virmidi_dev snd_virmidi_dev_t; +typedef struct snd_virmidi snd_virmidi_t; + +/* seq_instr */ +typedef struct snd_seq_kcluster snd_seq_kcluster_t; +typedef struct snd_seq_kinstr_ops snd_seq_kinstr_ops_t; +typedef struct snd_seq_kinstr snd_seq_kinstr_t; +typedef struct snd_seq_kinstr_list snd_seq_kinstr_list_t; + +/* ac97 */ +typedef struct snd_ac97_bus ac97_bus_t; +typedef struct snd_ac97_bus_ops ac97_bus_ops_t; +typedef struct snd_ac97_template ac97_template_t; +typedef struct snd_ac97 ac97_t; + +/* opl3/4 */ +typedef struct snd_opl3 opl3_t; +typedef struct snd_opl4 opl4_t; + +/* mpu401 */ +typedef struct snd_mpu401 mpu401_t; + +/* i2c */ +typedef struct snd_i2c_device snd_i2c_device_t; +typedef struct snd_i2c_bus snd_i2c_bus_t; + +typedef struct snd_ak4531 ak4531_t; + diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index c39b3802cf18..20f7babad514 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ -#define CONFIG_SND_VERSION "1.0.14rc2" -#define CONFIG_SND_DATE " (Fri Feb 09 13:50:10 2007 UTC)" +#define CONFIG_SND_VERSION "1.0.14rc1" +#define CONFIG_SND_DATE " (Tue Jan 09 09:56:17 2007 UTC)" diff --git a/trunk/include/sound/vx_core.h b/trunk/include/sound/vx_core.h index 4830651cc4cf..217394652090 100644 --- a/trunk/include/sound/vx_core.h +++ b/trunk/include/sound/vx_core.h @@ -128,7 +128,7 @@ struct snd_vx_hardware { unsigned int num_ins; unsigned int num_outs; unsigned int output_level_max; - const unsigned int *output_level_db_scale; + unsigned int *output_level_db_scale; }; /* hwdep id string */ diff --git a/trunk/include/sound/ymfpci.h b/trunk/include/sound/ymfpci.h index 203d2b45b788..f3514ee96bd9 100644 --- a/trunk/include/sound/ymfpci.h +++ b/trunk/include/sound/ymfpci.h @@ -270,7 +270,6 @@ struct snd_ymfpci_pcm { struct snd_pcm_substream *substream; struct snd_ymfpci_voice *voices[2]; /* playback only */ unsigned int running: 1, - use_441_slot: 1, output_front: 1, output_rear: 1, swap_rear: 1; @@ -325,7 +324,6 @@ struct snd_ymfpci { u32 active_bank; struct snd_ymfpci_voice voices[64]; - int src441_used; struct snd_ac97_bus *ac97_bus; struct snd_ac97 *ac97; @@ -348,7 +346,7 @@ struct snd_ymfpci { int mode_dup4ch; int rear_opened; int spdif_opened; - struct snd_ymfpci_pcm_mixer { + struct { u16 left; u16 right; struct snd_kcontrol *ctl; @@ -359,8 +357,6 @@ struct snd_ymfpci { wait_queue_head_t interrupt_sleep; atomic_t interrupt_sleep_count; struct snd_info_entry *proc_entry; - const struct firmware *dsp_microcode; - const struct firmware *controller_microcode; #ifdef CONFIG_PM u32 *saved_regs; diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index f30ef28405d3..8332c77b1bd1 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -605,6 +605,26 @@ struct page * find_get_page(struct address_space *mapping, unsigned long offset) } EXPORT_SYMBOL(find_get_page); +/** + * find_trylock_page - find and lock a page + * @mapping: the address_space to search + * @offset: the page index + * + * Same as find_get_page(), but trylock it instead of incrementing the count. + */ +struct page *find_trylock_page(struct address_space *mapping, unsigned long offset) +{ + struct page *page; + + read_lock_irq(&mapping->tree_lock); + page = radix_tree_lookup(&mapping->page_tree, offset); + if (page && TestSetPageLocked(page)) + page = NULL; + read_unlock_irq(&mapping->tree_lock); + return page; +} +EXPORT_SYMBOL(find_trylock_page); + /** * find_lock_page - locate, pin and lock a pagecache page * @mapping: the address_space to search diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 915657832d94..7dfc94920697 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -37,7 +37,6 @@ config NETDEBUG source "net/packet/Kconfig" source "net/unix/Kconfig" source "net/xfrm/Kconfig" -source "net/iucv/Kconfig" config INET bool "TCP/IP networking" diff --git a/trunk/net/Makefile b/trunk/net/Makefile index 4854ac506313..ad4d14f4bb29 100644 --- a/trunk/net/Makefile +++ b/trunk/net/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_IP_SCTP) += sctp/ obj-$(CONFIG_IEEE80211) += ieee80211/ obj-$(CONFIG_TIPC) += tipc/ obj-$(CONFIG_NETLABEL) += netlabel/ -obj-$(CONFIG_IUCV) += iucv/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/trunk/net/atm/common.c b/trunk/net/atm/common.c index a2878e92c3ab..fbabff494468 100644 --- a/trunk/net/atm/common.c +++ b/trunk/net/atm/common.c @@ -816,8 +816,7 @@ static void __exit atm_exit(void) proto_unregister(&vcc_proto); } -subsys_initcall(atm_init); - +module_init(atm_init); module_exit(atm_exit); MODULE_LICENSE("GPL"); diff --git a/trunk/net/bluetooth/hidp/hidp.h b/trunk/net/bluetooth/hidp/hidp.h index c8dfacd40a06..c2775f587d2e 100644 --- a/trunk/net/bluetooth/hidp/hidp.h +++ b/trunk/net/bluetooth/hidp/hidp.h @@ -86,7 +86,7 @@ struct hidp_connadd_req { int intr_sock; // Connteted interrupt socket __u16 parser; __u16 rd_size; - __u8 __user *rd_data; + __u8 *rd_data; __u8 country; __u8 subclass; __u16 vendor; diff --git a/trunk/net/bluetooth/hidp/sock.c b/trunk/net/bluetooth/hidp/sock.c index 93cf9e586178..407fba43c1b9 100644 --- a/trunk/net/bluetooth/hidp/sock.c +++ b/trunk/net/bluetooth/hidp/sock.c @@ -189,7 +189,7 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne uca = compat_alloc_user_space(sizeof(*uca)); - if (copy_from_user(&ca, (void __user *) arg, sizeof(ca))) + if (copy_from_user(&ca, (void *) arg, sizeof(ca))) return -EFAULT; if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index a25fa8cb5284..ea3337ad0edc 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -949,29 +949,44 @@ static ctl_table brnf_net_table[] = { }; #endif -int __init br_netfilter_init(void) +int br_netfilter_init(void) { - int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) { + int ret; + + if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0) + continue; + + while (i--) + nf_unregister_hook(&br_nf_ops[i]); - ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); - if (ret < 0) return ret; + } + #ifdef CONFIG_SYSCTL brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0); if (brnf_sysctl_header == NULL) { printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); - nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); - return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) + nf_unregister_hook(&br_nf_ops[i]); + return -EFAULT; } #endif + printk(KERN_NOTICE "Bridge firewalling registered\n"); + return 0; } void br_netfilter_fini(void) { - nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + int i; + + for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--) + nf_unregister_hook(&br_nf_ops[i]); #ifdef CONFIG_SYSCTL unregister_sysctl_table(brnf_sysctl_header); #endif diff --git a/trunk/net/bridge/br_netlink.c b/trunk/net/bridge/br_netlink.c index 7d68b24b5654..a9139682c49b 100644 --- a/trunk/net/bridge/br_netlink.c +++ b/trunk/net/bridge/br_netlink.c @@ -45,7 +45,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_BRIDGE; @@ -72,8 +72,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } /* @@ -90,12 +89,9 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port) goto errout; err = br_fill_ifinfo(skb, port, 0, 0, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in br_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in br_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); errout: if (err < 0) diff --git a/trunk/net/bridge/netfilter/ebt_ip.c b/trunk/net/bridge/netfilter/ebt_ip.c index 6afa4d017d4a..e4c642448e1b 100644 --- a/trunk/net/bridge/netfilter/ebt_ip.c +++ b/trunk/net/bridge/netfilter/ebt_ip.c @@ -93,7 +93,6 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask, return -EINVAL; if (info->protocol != IPPROTO_TCP && info->protocol != IPPROTO_UDP && - info->protocol != IPPROTO_UDPLITE && info->protocol != IPPROTO_SCTP && info->protocol != IPPROTO_DCCP) return -EINVAL; diff --git a/trunk/net/bridge/netfilter/ebt_log.c b/trunk/net/bridge/netfilter/ebt_log.c index 985df82e427b..a184f879f253 100644 --- a/trunk/net/bridge/netfilter/ebt_log.c +++ b/trunk/net/bridge/netfilter/ebt_log.c @@ -96,7 +96,6 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum, NIPQUAD(ih->daddr), ih->tos, ih->protocol); if (ih->protocol == IPPROTO_TCP || ih->protocol == IPPROTO_UDP || - ih->protocol == IPPROTO_UDPLITE || ih->protocol == IPPROTO_SCTP || ih->protocol == IPPROTO_DCCP) { struct tcpudphdr _ports, *pptr; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 1e94a1b9a0f4..455d589683e8 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -3247,7 +3247,7 @@ void synchronize_net(void) * unregister_netdev() instead of this. */ -void unregister_netdevice(struct net_device *dev) +int unregister_netdevice(struct net_device *dev) { struct net_device *d, **dp; @@ -3258,9 +3258,7 @@ void unregister_netdevice(struct net_device *dev) if (dev->reg_state == NETREG_UNINITIALIZED) { printk(KERN_DEBUG "unregister_netdevice: device %s/%p never " "was registered\n", dev->name, dev); - - WARN_ON(1); - return; + return -ENODEV; } BUG_ON(dev->reg_state != NETREG_REGISTERED); @@ -3282,7 +3280,11 @@ void unregister_netdevice(struct net_device *dev) break; } } - BUG_ON(!d); + if (!d) { + printk(KERN_ERR "unregister net_device: '%s' not found\n", + dev->name); + return -ENODEV; + } dev->reg_state = NETREG_UNREGISTERING; @@ -3314,6 +3316,7 @@ void unregister_netdevice(struct net_device *dev) synchronize_net(); dev_put(dev); + return 0; } /** diff --git a/trunk/net/core/dst.c b/trunk/net/core/dst.c index 1a53fb39b7e0..836ec6606925 100644 --- a/trunk/net/core/dst.c +++ b/trunk/net/core/dst.c @@ -99,14 +99,7 @@ static void dst_run_gc(unsigned long dummy) printk("dst_total: %d/%d %ld\n", atomic_read(&dst_total), delayed, dst_gc_timer_expires); #endif - /* if the next desired timer is more than 4 seconds in the future - * then round the timer to whole seconds - */ - if (dst_gc_timer_expires > 4*HZ) - mod_timer(&dst_gc_timer, - round_jiffies(jiffies + dst_gc_timer_expires)); - else - mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires); + mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires); out: spin_unlock(&dst_lock); diff --git a/trunk/net/core/fib_rules.c b/trunk/net/core/fib_rules.c index 215f1bff048f..1df6cd4568d3 100644 --- a/trunk/net/core/fib_rules.c +++ b/trunk/net/core/fib_rules.c @@ -331,7 +331,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*frh), flags); if (nlh == NULL) - return -EMSGSIZE; + return -1; frh = nlmsg_data(nlh); frh->table = rule->table; @@ -359,8 +359,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family) @@ -406,12 +405,9 @@ static void notify_rule_change(int event, struct fib_rule *rule, goto errout; err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); - if (err < 0) { - /* -EMSGSIZE implies BUG in fib_rule_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in fib_rule_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); errout: if (err < 0) diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 054d46493d2b..e7300b6b4079 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -696,10 +696,7 @@ static void neigh_periodic_timer(unsigned long arg) if (!expire) expire = 1; - if (expire>HZ) - mod_timer(&tbl->gc_timer, round_jiffies(now + expire)); - else - mod_timer(&tbl->gc_timer, now + expire); + mod_timer(&tbl->gc_timer, now + expire); write_unlock(&tbl->lock); } @@ -1640,7 +1637,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ndtmsg = nlmsg_data(nlh); @@ -1709,8 +1706,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, nla_put_failure: read_unlock_bh(&tbl->lock); - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static int neightbl_fill_param_info(struct sk_buff *skb, @@ -1724,7 +1720,7 @@ static int neightbl_fill_param_info(struct sk_buff *skb, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndtmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ndtmsg = nlmsg_data(nlh); @@ -1741,8 +1737,7 @@ static int neightbl_fill_param_info(struct sk_buff *skb, return nlmsg_end(skb, nlh); errout: read_unlock_bh(&tbl->lock); - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, @@ -1960,7 +1955,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ndm = nlmsg_data(nlh); ndm->ndm_family = neigh->ops->family; @@ -1992,8 +1987,7 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } @@ -2435,12 +2429,9 @@ static void __neigh_notify(struct neighbour *n, int type, int flags) goto errout; err = neigh_fill_info(skb, n, 0, 0, type, flags); - if (err < 0) { - /* -EMSGSIZE implies BUG in neigh_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in neigh_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); errout: if (err < 0) diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 9bf9ae05f157..e76539a5eb5e 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -320,7 +320,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ifm = nlmsg_data(nlh); ifm->ifi_family = AF_UNSPEC; @@ -384,8 +384,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) @@ -634,12 +633,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in if_nlmsg_size */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(nskb); - goto errout; - } + /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */ + BUG_ON(err < 0); + err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); errout: kfree(iw_buf); @@ -682,12 +678,9 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) goto errout; err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in if_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in if_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); errout: if (err < 0) diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index 5c452a3ec4d1..40402c59506a 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -479,8 +479,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) ccid3_pr_debug("%s(%p), s=%u, w_init=%llu, " "R_sample=%dus, X=%u\n", dccp_role(sk), - sk, hctx->ccid3hctx_s, - (unsigned long long)w_init, + sk, hctx->ccid3hctx_s, w_init, (int)r_sample, (unsigned)(hctx->ccid3hctx_x >> 6)); @@ -1006,7 +1005,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) DCCP_BUG_ON(r_sample < 0); if (unlikely(r_sample <= t_elapsed)) DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n", - (long)r_sample, (long)t_elapsed); + r_sample, t_elapsed); else r_sample -= t_elapsed; CCID3_RTT_SANITY_CHECK(r_sample); diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index fa2c982d4309..90c74b4adb73 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -72,7 +72,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) tmp = ip_route_connect(&rt, nexthop, inet->saddr, RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, IPPROTO_DCCP, - inet->sport, usin->sin_port, sk, 1); + inet->sport, usin->sin_port, sk); if (tmp < 0) return tmp; diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index 79140b3e592e..6b91a9dd0411 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -1041,7 +1041,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - err = xfrm_lookup(&dst, &fl, sk, 1); + err = xfrm_lookup(&dst, &fl, sk, 0); if (err < 0) goto failure; diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index 48438565d70f..63b3fa20e14b 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -1024,6 +1024,7 @@ static int __init dccp_init(void) do { dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE / sizeof(struct inet_ehash_bucket); + dccp_hashinfo.ehash_size >>= 1; while (dccp_hashinfo.ehash_size & (dccp_hashinfo.ehash_size - 1)) dccp_hashinfo.ehash_size--; @@ -1036,10 +1037,9 @@ static int __init dccp_init(void) goto out_free_bind_bucket_cachep; } - for (i = 0; i < dccp_hashinfo.ehash_size; i++) { + for (i = 0; i < (dccp_hashinfo.ehash_size << 1); i++) { rwlock_init(&dccp_hashinfo.ehash[i].lock); INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain); - INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain); } bhash_order = ehash_order; diff --git a/trunk/net/decnet/dn_dev.c b/trunk/net/decnet/dn_dev.c index 90b3dfd72b49..ed083ab455b7 100644 --- a/trunk/net/decnet/dn_dev.c +++ b/trunk/net/decnet/dn_dev.c @@ -749,7 +749,7 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ifm = nlmsg_data(nlh); ifm->ifa_family = AF_DECnet; @@ -768,8 +768,7 @@ static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) @@ -782,12 +781,9 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) goto errout; err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in dn_ifaddr_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in dn_ifaddr_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); errout: if (err < 0) diff --git a/trunk/net/decnet/dn_table.c b/trunk/net/decnet/dn_table.c index c1f0cc1b1c60..13b2421991ba 100644 --- a/trunk/net/decnet/dn_table.c +++ b/trunk/net/decnet/dn_table.c @@ -350,7 +350,7 @@ static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nlmsg_failure: rtattr_failure: skb_trim(skb, b - skb->data); - return -EMSGSIZE; + return -1; } @@ -368,12 +368,9 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id, err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, f->fn_type, f->fn_scope, &f->fn_key, z, DN_FIB_INFO(f), 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in dn_fib_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); errout: if (err < 0) diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index 5750a2b2a0d6..864009643675 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -1007,7 +1007,7 @@ static int inet_sk_reselect_saddr(struct sock *sk) RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, sk->sk_protocol, - inet->sport, inet->dport, sk, 0); + inet->sport, inet->dport, sk); if (err) return err; diff --git a/trunk/net/ipv4/datagram.c b/trunk/net/ipv4/datagram.c index 0072d79f0c2a..7b068a891953 100644 --- a/trunk/net/ipv4/datagram.c +++ b/trunk/net/ipv4/datagram.c @@ -49,7 +49,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, RT_CONN_FLAGS(sk), oif, sk->sk_protocol, - inet->sport, usin->sin_port, sk, 1); + inet->sport, usin->sin_port, sk); if (err) return err; if ((rt->rt_flags & RTCF_BROADCAST) && !sock_flag(sk, SOCK_BROADCAST)) { diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index c40203640966..480ace9819f6 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -1140,7 +1140,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; ifm = nlmsg_data(nlh); ifm->ifa_family = AF_INET; @@ -1167,8 +1167,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) @@ -1226,12 +1225,9 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh, goto errout; err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in inet_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in inet_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL); errout: if (err < 0) diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index be1028c9933e..e63b8a98fb4d 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -314,12 +314,9 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, err = fib_dump_info(skb, info->pid, seq, event, tb_id, fa->fa_type, fa->fa_scope, key, dst_len, fa->fa_tos, fa->fa_info, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in fib_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in fib_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE, info->nlh, GFP_KERNEL); errout: @@ -963,7 +960,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; rtm = nlmsg_data(nlh); rtm->rtm_family = AF_INET; @@ -1034,8 +1031,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } /* diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 024ae56cab25..0017ccb01d6d 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -455,8 +455,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, skb = add_grhead(skb, pmc, type, &pgr); first = 0; } - if (!skb) - return NULL; psrc = (__be32 *)skb_put(skb, sizeof(__be32)); *psrc = psf->sf_inaddr; scount++; stotal++; diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 8aa7d51e6881..77761ac4f7bb 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -153,7 +153,7 @@ static int inet_csk_diag_fill(struct sock *sk, rtattr_failure: nlmsg_failure: skb_trim(skb, b - skb->data); - return -EMSGSIZE; + return -1; } static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, @@ -209,7 +209,7 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, return skb->len; nlmsg_failure: skb_trim(skb, previous_tail - skb->data); - return -EMSGSIZE; + return -1; } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, @@ -274,14 +274,11 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, if (!rep) goto out; - err = sk_diag_fill(sk, rep, req->idiag_ext, - NETLINK_CB(in_skb).pid, - nlh->nlmsg_seq, 0, nlh); - if (err < 0) { - WARN_ON(err == -EMSGSIZE); - kfree_skb(rep); - goto out; - } + if (sk_diag_fill(sk, rep, req->idiag_ext, + NETLINK_CB(in_skb).pid, + nlh->nlmsg_seq, 0, nlh) <= 0) + BUG(); + err = netlink_unicast(idiagnl, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) @@ -778,7 +775,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) struct inet_timewait_sock *tw; inet_twsk_for_each(tw, node, - &head->twchain) { + &hashinfo->ehash[i + hashinfo->ehash_size].chain) { if (num < s_num) goto next_dying; diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 150ace18dc75..8c79c8a4ea5c 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -212,7 +212,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, write_lock(&head->lock); /* Check TIME-WAIT sockets first. */ - sk_for_each(sk2, node, &head->twchain) { + sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { tw = inet_twsk(sk2); if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index a73cf93cee36..9f414e35c488 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -78,8 +78,8 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, if (__sk_del_node_init(sk)) sock_prot_dec_use(sk->sk_prot); - /* Step 3: Hash TW into TIMEWAIT chain. */ - inet_twsk_add_node(tw, &ehead->twchain); + /* Step 3: Hash TW into TIMEWAIT half of established hash table. */ + inet_twsk_add_node(tw, &(ehead + hashinfo->ehash_size)->chain); atomic_inc(&tw->tw_refcnt); write_unlock(&ehead->lock); diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 51c83500790f..476cb6084c75 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -1008,8 +1008,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) goto done; dev = t->dev; } - unregister_netdevice(dev); - err = 0; + err = unregister_netdevice(dev); break; default: diff --git a/trunk/net/ipv4/ipip.c b/trunk/net/ipv4/ipip.c index da8bbd20c7ed..9d719d664e5b 100644 --- a/trunk/net/ipv4/ipip.c +++ b/trunk/net/ipv4/ipip.c @@ -754,8 +754,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) goto done; dev = t->dev; } - unregister_netdevice(dev); - err = 0; + err = unregister_netdevice(dev); break; default: diff --git a/trunk/net/ipv4/netfilter/Kconfig b/trunk/net/ipv4/netfilter/Kconfig index 9b08e7ad71bc..47bd3ad18b71 100644 --- a/trunk/net/ipv4/netfilter/Kconfig +++ b/trunk/net/ipv4/netfilter/Kconfig @@ -361,6 +361,32 @@ config IP_NF_TARGET_ULOG To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_TCPMSS + tristate "TCPMSS target support" + depends on IP_NF_IPTABLES + ---help--- + This option adds a `TCPMSS' target, which allows you to alter the + MSS value of TCP SYN packets, to control the maximum size for that + connection (usually limiting it to your outgoing interface's MTU + minus 40). + + This is used to overcome criminally braindead ISPs or servers which + block ICMP Fragmentation Needed packets. The symptoms of this + problem are that everything works fine from your Linux + firewall/router, but machines behind it can never exchange large + packets: + 1) Web browsers connect, then hang with no data received. + 2) Small mail works fine, but large emails hang. + 3) ssh works fine, but scp hangs after initial handshaking. + + Workaround: activate this option and add a rule to your firewall + configuration like: + + iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ + -j TCPMSS --clamp-mss-to-pmtu + + To compile it as a module, choose M here. If unsure, say N. + # NAT + specific targets: ip_conntrack config IP_NF_NAT tristate "Full NAT" diff --git a/trunk/net/ipv4/netfilter/Makefile b/trunk/net/ipv4/netfilter/Makefile index 6625ec68180c..16d177b71bf8 100644 --- a/trunk/net/ipv4/netfilter/Makefile +++ b/trunk/net/ipv4/netfilter/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o +obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/trunk/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index c34f48fe5478..06e4e8a6dd9f 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -50,9 +50,12 @@ static DEFINE_RWLOCK(tcp_lock); If it's non-zero, we mark only out of window RST segments as INVALID. */ int ip_ct_tcp_be_liberal __read_mostly = 0; -/* If it is set to zero, we disable picking up already established +/* When connection is picked up from the middle, how many packets are required + to pass in each direction when we assume we are in sync - if any side uses + window scaling, we lost the game. + If it is set to zero, we disable picking up already established connections. */ -int ip_ct_tcp_loose __read_mostly = 1; +int ip_ct_tcp_loose __read_mostly = 3; /* Max number of the retransmitted packets without receiving an (acceptable) ACK from the destination. If this number is reached, a shorter timer @@ -691,10 +694,11 @@ static int tcp_in_window(struct ip_ct_tcp *state, before(sack, receiver->td_end + 1), after(ack, receiver->td_end - MAXACKWINDOW(sender))); - if (before(seq, sender->td_maxend + 1) && - after(end, sender->td_end - receiver->td_maxwin - 1) && - before(sack, receiver->td_end + 1) && - after(ack, receiver->td_end - MAXACKWINDOW(sender))) { + if (sender->loose || receiver->loose || + (before(seq, sender->td_maxend + 1) && + after(end, sender->td_end - receiver->td_maxwin - 1) && + before(sack, receiver->td_end + 1) && + after(ack, receiver->td_end - MAXACKWINDOW(sender)))) { /* * Take into account window scaling (RFC 1323). */ @@ -739,13 +743,15 @@ static int tcp_in_window(struct ip_ct_tcp *state, state->retrans = 0; } } + /* + * Close the window of disabled window tracking :-) + */ + if (sender->loose) + sender->loose--; + res = 1; } else { - res = 0; - if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || - ip_ct_tcp_be_liberal) - res = 1; - if (!res && LOG_INVALID(IPPROTO_TCP)) + if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, "ip_ct_tcp: %s ", before(seq, sender->td_maxend + 1) ? @@ -756,6 +762,8 @@ static int tcp_in_window(struct ip_ct_tcp *state, : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); + + res = ip_ct_tcp_be_liberal; } DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " @@ -1097,6 +1105,8 @@ static int tcp_new(struct ip_conntrack *conntrack, tcp_options(skb, iph, th, &conntrack->proto.tcp.seen[0]); conntrack->proto.tcp.seen[1].flags = 0; + conntrack->proto.tcp.seen[0].loose = + conntrack->proto.tcp.seen[1].loose = 0; } else if (ip_ct_tcp_loose == 0) { /* Don't try to pick up connections. */ return 0; @@ -1117,11 +1127,11 @@ static int tcp_new(struct ip_conntrack *conntrack, conntrack->proto.tcp.seen[0].td_maxwin; conntrack->proto.tcp.seen[0].td_scale = 0; - /* We assume SACK and liberal window checking to handle - * window scaling */ + /* We assume SACK. Should we assume window scaling too? */ conntrack->proto.tcp.seen[0].flags = - conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM | - IP_CT_TCP_FLAG_BE_LIBERAL; + conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM; + conntrack->proto.tcp.seen[0].loose = + conntrack->proto.tcp.seen[1].loose = ip_ct_tcp_loose; } conntrack->proto.tcp.seen[1].td_end = 0; diff --git a/trunk/net/ipv4/netfilter/ip_nat_core.c b/trunk/net/ipv4/netfilter/ip_nat_core.c index 5e08c2bf887d..9d1a5175dcd4 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_core.c +++ b/trunk/net/ipv4/netfilter/ip_nat_core.c @@ -246,9 +246,8 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple, if (maniptype == IP_NAT_MANIP_SRC) { if (find_appropriate_src(orig_tuple, tuple, range)) { DEBUGP("get_unique_tuple: Found current src map\n"); - if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) - if (!ip_nat_used_tuple(tuple, conntrack)) - return; + if (!ip_nat_used_tuple(tuple, conntrack)) + return; } } @@ -262,13 +261,6 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple, proto = ip_nat_proto_find_get(orig_tuple->dst.protonum); - /* Change protocol info to have some randomization */ - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) { - proto->unique_tuple(tuple, range, maniptype, conntrack); - ip_nat_proto_put(proto); - return; - } - /* Only bother mapping if it's not already in range and unique */ if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || proto->in_range(tuple, maniptype, &range->min, &range->max)) diff --git a/trunk/net/ipv4/netfilter/ip_nat_helper.c b/trunk/net/ipv4/netfilter/ip_nat_helper.c index 2e5c4bc52a60..ee80feb4b2a9 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_helper.c +++ b/trunk/net/ipv4/netfilter/ip_nat_helper.c @@ -183,7 +183,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb, datalen = (*pskb)->len - iph->ihl*4; if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) { tcph->check = 0; - tcph->check = tcp_v4_check(datalen, + tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr, csum_partial((char *)tcph, datalen, 0)); diff --git a/trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c b/trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c index 14ff24f53a7a..b586d18b3fb3 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c +++ b/trunk/net/ipv4/netfilter/ip_nat_proto_tcp.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -76,10 +75,6 @@ tcp_unique_tuple(struct ip_conntrack_tuple *tuple, range_size = ntohs(range->max.tcp.port) - min + 1; } - /* Start from random port to avoid prediction */ - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) - port = net_random(); - for (i = 0; i < range_size; i++, port++) { *portptr = htons(min + port % range_size); if (!ip_nat_used_tuple(tuple, conntrack)) { diff --git a/trunk/net/ipv4/netfilter/ip_nat_proto_udp.c b/trunk/net/ipv4/netfilter/ip_nat_proto_udp.c index dfd521672891..5ced0877b32f 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_proto_udp.c +++ b/trunk/net/ipv4/netfilter/ip_nat_proto_udp.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -75,10 +74,6 @@ udp_unique_tuple(struct ip_conntrack_tuple *tuple, range_size = ntohs(range->max.udp.port) - min + 1; } - /* Start from random port to avoid prediction */ - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) - port = net_random(); - for (i = 0; i < range_size; i++, port++) { *portptr = htons(min + port % range_size); if (!ip_nat_used_tuple(tuple, conntrack)) diff --git a/trunk/net/ipv4/netfilter/ip_nat_rule.c b/trunk/net/ipv4/netfilter/ip_nat_rule.c index e1c8a05f3dc6..a176aa3031e0 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_rule.c +++ b/trunk/net/ipv4/netfilter/ip_nat_rule.c @@ -86,7 +86,7 @@ static struct } }; -static struct xt_table nat_table = { +static struct ipt_table nat_table = { .name = "nat", .valid_hooks = NAT_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, @@ -99,7 +99,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, - const struct xt_target *target, + const struct ipt_target *target, const void *targinfo) { struct ip_conntrack *ct; @@ -141,7 +141,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, - const struct xt_target *target, + const struct ipt_target *target, const void *targinfo) { struct ip_conntrack *ct; @@ -166,7 +166,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, static int ipt_snat_checkentry(const char *tablename, const void *entry, - const struct xt_target *target, + const struct ipt_target *target, void *targinfo, unsigned int hook_mask) { @@ -182,7 +182,7 @@ static int ipt_snat_checkentry(const char *tablename, static int ipt_dnat_checkentry(const char *tablename, const void *entry, - const struct xt_target *target, + const struct ipt_target *target, void *targinfo, unsigned int hook_mask) { @@ -193,10 +193,6 @@ static int ipt_dnat_checkentry(const char *tablename, printk("DNAT: multiple ranges no longer supported\n"); return 0; } - if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) { - printk("DNAT: port randomization not supported\n"); - return 0; - } return 1; } @@ -261,9 +257,8 @@ int ip_nat_rule_find(struct sk_buff **pskb, return ret; } -static struct xt_target ipt_snat_reg = { +static struct ipt_target ipt_snat_reg = { .name = "SNAT", - .family = AF_INET, .target = ipt_snat_target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", @@ -271,9 +266,8 @@ static struct xt_target ipt_snat_reg = { .checkentry = ipt_snat_checkentry, }; -static struct xt_target ipt_dnat_reg = { +static struct ipt_target ipt_dnat_reg = { .name = "DNAT", - .family = AF_INET, .target = ipt_dnat_target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", @@ -288,27 +282,27 @@ int __init ip_nat_rule_init(void) ret = ipt_register_table(&nat_table, &nat_initial_table.repl); if (ret != 0) return ret; - ret = xt_register_target(&ipt_snat_reg); + ret = ipt_register_target(&ipt_snat_reg); if (ret != 0) goto unregister_table; - ret = xt_register_target(&ipt_dnat_reg); + ret = ipt_register_target(&ipt_dnat_reg); if (ret != 0) goto unregister_snat; return ret; unregister_snat: - xt_unregister_target(&ipt_snat_reg); + ipt_unregister_target(&ipt_snat_reg); unregister_table: - xt_unregister_table(&nat_table); + ipt_unregister_table(&nat_table); return ret; } void ip_nat_rule_cleanup(void) { - xt_unregister_target(&ipt_dnat_reg); - xt_unregister_target(&ipt_snat_reg); + ipt_unregister_target(&ipt_dnat_reg); + ipt_unregister_target(&ipt_snat_reg); ipt_unregister_table(&nat_table); } diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index 5a7b3a341389..fc1f153c86ba 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -216,7 +216,7 @@ ipt_do_table(struct sk_buff **pskb, unsigned int hook, const struct net_device *in, const struct net_device *out, - struct xt_table *table) + struct ipt_table *table) { static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); u_int16_t offset; @@ -507,7 +507,7 @@ check_entry(struct ipt_entry *e, const char *name) static inline int check_match(struct ipt_entry_match *m, const char *name, const struct ipt_ip *ip, unsigned int hookmask) { - struct xt_match *match; + struct ipt_match *match; int ret; match = m->u.kernel.match; @@ -531,7 +531,7 @@ find_check_match(struct ipt_entry_match *m, unsigned int hookmask, unsigned int *i) { - struct xt_match *match; + struct ipt_match *match; int ret; match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, @@ -557,7 +557,7 @@ find_check_match(struct ipt_entry_match *m, static inline int check_target(struct ipt_entry *e, const char *name) { struct ipt_entry_target *t; - struct xt_target *target; + struct ipt_target *target; int ret; t = ipt_get_target(e); @@ -580,7 +580,7 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, unsigned int *i) { struct ipt_entry_target *t; - struct xt_target *target; + struct ipt_target *target; int ret; unsigned int j; @@ -818,7 +818,7 @@ get_counters(const struct xt_table_info *t, } } -static inline struct xt_counters * alloc_counters(struct xt_table *table) +static inline struct xt_counters * alloc_counters(struct ipt_table *table) { unsigned int countersize; struct xt_counters *counters; @@ -843,7 +843,7 @@ static inline struct xt_counters * alloc_counters(struct xt_table *table) static int copy_entries_to_user(unsigned int total_size, - struct xt_table *table, + struct ipt_table *table, void __user *userptr) { unsigned int off, num; @@ -1046,7 +1046,7 @@ static int compat_table_info(struct xt_table_info *info, static int get_info(void __user *user, int *len, int compat) { char name[IPT_TABLE_MAXNAMELEN]; - struct xt_table *t; + struct ipt_table *t; int ret; if (*len != sizeof(struct ipt_getinfo)) { @@ -1107,7 +1107,7 @@ get_entries(struct ipt_get_entries __user *uptr, int *len) { int ret; struct ipt_get_entries get; - struct xt_table *t; + struct ipt_table *t; if (*len < sizeof(get)) { duprintf("get_entries: %u < %d\n", *len, @@ -1151,7 +1151,7 @@ __do_replace(const char *name, unsigned int valid_hooks, void __user *counters_ptr) { int ret; - struct xt_table *t; + struct ipt_table *t; struct xt_table_info *oldinfo; struct xt_counters *counters; void *loc_cpu_old_entry; @@ -1302,7 +1302,7 @@ do_add_counters(void __user *user, unsigned int len, int compat) char *name; int size; void *ptmp; - struct xt_table *t; + struct ipt_table *t; struct xt_table_info *private; int ret = 0; void *loc_cpu_entry; @@ -1437,7 +1437,7 @@ compat_check_calc_match(struct ipt_entry_match *m, unsigned int hookmask, int *size, int *i) { - struct xt_match *match; + struct ipt_match *match; match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, m->u.user.revision), @@ -1466,7 +1466,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, const char *name) { struct ipt_entry_target *t; - struct xt_target *target; + struct ipt_target *target; unsigned int entry_offset; int ret, off, h, j; @@ -1550,7 +1550,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, struct xt_table_info *newinfo, unsigned char *base) { struct ipt_entry_target *t; - struct xt_target *target; + struct ipt_target *target; struct ipt_entry *de; unsigned int origsize; int ret, h; @@ -1795,7 +1795,7 @@ struct compat_ipt_get_entries }; static int compat_copy_entries_to_user(unsigned int total_size, - struct xt_table *table, void __user *userptr) + struct ipt_table *table, void __user *userptr) { unsigned int off, num; struct compat_ipt_entry e; @@ -1869,7 +1869,7 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len) { int ret; struct compat_ipt_get_entries get; - struct xt_table *t; + struct ipt_table *t; if (*len < sizeof(get)) { @@ -2052,7 +2052,7 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) return 0; } -void ipt_unregister_table(struct xt_table *table) +void ipt_unregister_table(struct ipt_table *table) { struct xt_table_info *private; void *loc_cpu_entry; @@ -2124,7 +2124,7 @@ icmp_checkentry(const char *tablename, } /* The built-in targets: standard (NULL) and error. */ -static struct xt_target ipt_standard_target = { +static struct ipt_target ipt_standard_target = { .name = IPT_STANDARD_TARGET, .targetsize = sizeof(int), .family = AF_INET, @@ -2135,7 +2135,7 @@ static struct xt_target ipt_standard_target = { #endif }; -static struct xt_target ipt_error_target = { +static struct ipt_target ipt_error_target = { .name = IPT_ERROR_TARGET, .target = ipt_error, .targetsize = IPT_FUNCTION_MAXNAMELEN, @@ -2158,7 +2158,7 @@ static struct nf_sockopt_ops ipt_sockopts = { #endif }; -static struct xt_match icmp_matchstruct = { +static struct ipt_match icmp_matchstruct = { .name = "icmp", .match = icmp_match, .matchsize = sizeof(struct ipt_icmp), diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c index 343c2abdc1a0..b1c11160b9de 100644 --- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -26,7 +26,6 @@ #include -#include #include #include #include @@ -248,7 +247,6 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config) switch (iph->protocol) { case IPPROTO_TCP: case IPPROTO_UDP: - case IPPROTO_UDPLITE: case IPPROTO_SCTP: case IPPROTO_DCCP: case IPPROTO_ICMP: @@ -331,7 +329,7 @@ target(struct sk_buff **pskb, if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP && (ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY)) - return XT_CONTINUE; + return IPT_CONTINUE; /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, * TIMESTAMP, INFO_REQUEST or ADDRESS type icmp packets from here @@ -369,7 +367,7 @@ target(struct sk_buff **pskb, * actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */ (*pskb)->pkt_type = PACKET_HOST; - return XT_CONTINUE; + return IPT_CONTINUE; } static int @@ -472,9 +470,8 @@ static void destroy(const struct xt_target *target, void *targinfo) nf_ct_l3proto_module_put(target->family); } -static struct xt_target clusterip_tgt = { +static struct ipt_target clusterip_tgt = { .name = "CLUSTERIP", - .family = AF_INET, .target = target, .targetsize = sizeof(struct ipt_clusterip_tgt_info), .checkentry = checkentry, @@ -730,7 +727,7 @@ static int __init ipt_clusterip_init(void) { int ret; - ret = xt_register_target(&clusterip_tgt); + ret = ipt_register_target(&clusterip_tgt); if (ret < 0) return ret; @@ -756,7 +753,7 @@ static int __init ipt_clusterip_init(void) nf_unregister_hook(&cip_arp_ops); #endif /* CONFIG_PROC_FS */ cleanup_target: - xt_unregister_target(&clusterip_tgt); + ipt_unregister_target(&clusterip_tgt); return ret; } @@ -768,7 +765,7 @@ static void __exit ipt_clusterip_fini(void) remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); #endif nf_unregister_hook(&cip_arp_ops); - xt_unregister_target(&clusterip_tgt); + ipt_unregister_target(&clusterip_tgt); } module_init(ipt_clusterip_init); diff --git a/trunk/net/ipv4/netfilter/ipt_ECN.c b/trunk/net/ipv4/netfilter/ipt_ECN.c index b5ca5938d1fe..b55d670a24df 100644 --- a/trunk/net/ipv4/netfilter/ipt_ECN.c +++ b/trunk/net/ipv4/netfilter/ipt_ECN.c @@ -9,14 +9,12 @@ * ipt_ECN.c,v 1.5 2002/08/18 19:36:51 laforge Exp */ -#include #include #include #include #include #include -#include #include #include @@ -97,7 +95,7 @@ target(struct sk_buff **pskb, if (!set_ect_tcp(pskb, einfo)) return NF_DROP; - return XT_CONTINUE; + return IPT_CONTINUE; } static int @@ -121,7 +119,7 @@ checkentry(const char *tablename, return 0; } if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) - && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { + && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO))) { printk(KERN_WARNING "ECN: cannot use TCP operations on a " "non-tcp rule\n"); return 0; @@ -129,9 +127,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_target ipt_ecn_reg = { +static struct ipt_target ipt_ecn_reg = { .name = "ECN", - .family = AF_INET, .target = target, .targetsize = sizeof(struct ipt_ECN_info), .table = "mangle", @@ -141,12 +138,12 @@ static struct xt_target ipt_ecn_reg = { static int __init ipt_ecn_init(void) { - return xt_register_target(&ipt_ecn_reg); + return ipt_register_target(&ipt_ecn_reg); } static void __exit ipt_ecn_fini(void) { - xt_unregister_target(&ipt_ecn_reg); + ipt_unregister_target(&ipt_ecn_reg); } module_init(ipt_ecn_init); diff --git a/trunk/net/ipv4/netfilter/ipt_LOG.c b/trunk/net/ipv4/netfilter/ipt_LOG.c index f68370ffb43f..c96de16fefae 100644 --- a/trunk/net/ipv4/netfilter/ipt_LOG.c +++ b/trunk/net/ipv4/netfilter/ipt_LOG.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include MODULE_LICENSE("GPL"); @@ -432,7 +432,7 @@ ipt_log_target(struct sk_buff **pskb, ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); - return XT_CONTINUE; + return IPT_CONTINUE; } static int ipt_log_checkentry(const char *tablename, @@ -455,9 +455,8 @@ static int ipt_log_checkentry(const char *tablename, return 1; } -static struct xt_target ipt_log_reg = { +static struct ipt_target ipt_log_reg = { .name = "LOG", - .family = AF_INET, .target = ipt_log_target, .targetsize = sizeof(struct ipt_log_info), .checkentry = ipt_log_checkentry, @@ -472,11 +471,8 @@ static struct nf_logger ipt_log_logger ={ static int __init ipt_log_init(void) { - int ret; - - ret = xt_register_target(&ipt_log_reg); - if (ret < 0) - return ret; + if (ipt_register_target(&ipt_log_reg)) + return -EINVAL; if (nf_log_register(PF_INET, &ipt_log_logger) < 0) { printk(KERN_WARNING "ipt_LOG: not logging via system console " "since somebody else already registered for PF_INET\n"); @@ -490,7 +486,7 @@ static int __init ipt_log_init(void) static void __exit ipt_log_fini(void) { nf_log_unregister_logger(&ipt_log_logger); - xt_unregister_target(&ipt_log_reg); + ipt_unregister_target(&ipt_log_reg); } module_init(ipt_log_init); diff --git a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c index 91c42efcd533..d669685afd04 100644 --- a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -25,7 +25,7 @@ #else #include #endif -#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); @@ -190,9 +190,8 @@ static struct notifier_block masq_inet_notifier = { .notifier_call = masq_inet_event, }; -static struct xt_target masquerade = { +static struct ipt_target masquerade = { .name = "MASQUERADE", - .family = AF_INET, .target = masquerade_target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", @@ -205,7 +204,7 @@ static int __init ipt_masquerade_init(void) { int ret; - ret = xt_register_target(&masquerade); + ret = ipt_register_target(&masquerade); if (ret == 0) { /* Register for device down reports */ @@ -219,7 +218,7 @@ static int __init ipt_masquerade_init(void) static void __exit ipt_masquerade_fini(void) { - xt_unregister_target(&masquerade); + ipt_unregister_target(&masquerade); unregister_netdevice_notifier(&masq_dev_notifier); unregister_inetaddr_notifier(&masq_inet_notifier); } diff --git a/trunk/net/ipv4/netfilter/ipt_NETMAP.c b/trunk/net/ipv4/netfilter/ipt_NETMAP.c index b4acc241d898..9390e90f2b25 100644 --- a/trunk/net/ipv4/netfilter/ipt_NETMAP.c +++ b/trunk/net/ipv4/netfilter/ipt_NETMAP.c @@ -15,7 +15,6 @@ #include #include #include -#include #ifdef CONFIG_NF_NAT_NEEDED #include #else @@ -89,9 +88,8 @@ target(struct sk_buff **pskb, return ip_nat_setup_info(ct, &newrange, hooknum); } -static struct xt_target target_module = { +static struct ipt_target target_module = { .name = MODULENAME, - .family = AF_INET, .target = target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", @@ -103,12 +101,12 @@ static struct xt_target target_module = { static int __init ipt_netmap_init(void) { - return xt_register_target(&target_module); + return ipt_register_target(&target_module); } static void __exit ipt_netmap_fini(void) { - xt_unregister_target(&target_module); + ipt_unregister_target(&target_module); } module_init(ipt_netmap_init); diff --git a/trunk/net/ipv4/netfilter/ipt_REDIRECT.c b/trunk/net/ipv4/netfilter/ipt_REDIRECT.c index 54cd021aa5a8..462eceb3a1b1 100644 --- a/trunk/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REDIRECT.c @@ -18,7 +18,6 @@ #include #include #include -#include #ifdef CONFIG_NF_NAT_NEEDED #include #else @@ -105,9 +104,8 @@ redirect_target(struct sk_buff **pskb, return ip_nat_setup_info(ct, &newrange, hooknum); } -static struct xt_target redirect_reg = { +static struct ipt_target redirect_reg = { .name = "REDIRECT", - .family = AF_INET, .target = redirect_target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", @@ -118,12 +116,12 @@ static struct xt_target redirect_reg = { static int __init ipt_redirect_init(void) { - return xt_register_target(&redirect_reg); + return ipt_register_target(&redirect_reg); } static void __exit ipt_redirect_fini(void) { - xt_unregister_target(&redirect_reg); + ipt_unregister_target(&redirect_reg); } module_init(ipt_redirect_init); diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index e4a1ddb386a7..f0319e5ee437 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_BRIDGE_NETFILTER @@ -117,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) /* Adjust TCP checksum */ tcph->check = 0; - tcph->check = tcp_v4_check(sizeof(struct tcphdr), + tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), nskb->nh.iph->saddr, nskb->nh.iph->daddr, csum_partial((char *)tcph, @@ -231,7 +230,7 @@ static int check(const char *tablename, } else if (rejinfo->with == IPT_TCP_RESET) { /* Must specify that it's a TCP packet */ if (e->ip.proto != IPPROTO_TCP - || (e->ip.invflags & XT_INV_PROTO)) { + || (e->ip.invflags & IPT_INV_PROTO)) { DEBUGP("REJECT: TCP_RESET invalid for non-tcp\n"); return 0; } @@ -239,9 +238,8 @@ static int check(const char *tablename, return 1; } -static struct xt_target ipt_reject_reg = { +static struct ipt_target ipt_reject_reg = { .name = "REJECT", - .family = AF_INET, .target = reject, .targetsize = sizeof(struct ipt_reject_info), .table = "filter", @@ -253,12 +251,12 @@ static struct xt_target ipt_reject_reg = { static int __init ipt_reject_init(void) { - return xt_register_target(&ipt_reject_reg); + return ipt_register_target(&ipt_reject_reg); } static void __exit ipt_reject_fini(void) { - xt_unregister_target(&ipt_reject_reg); + ipt_unregister_target(&ipt_reject_reg); } module_init(ipt_reject_init); diff --git a/trunk/net/ipv4/netfilter/ipt_SAME.c b/trunk/net/ipv4/netfilter/ipt_SAME.c index a1cdd1262de2..3dcf29411337 100644 --- a/trunk/net/ipv4/netfilter/ipt_SAME.c +++ b/trunk/net/ipv4/netfilter/ipt_SAME.c @@ -34,7 +34,6 @@ #include #include #include -#include #ifdef CONFIG_NF_NAT_NEEDED #include #else @@ -187,9 +186,8 @@ same_target(struct sk_buff **pskb, return ip_nat_setup_info(ct, &newrange, hooknum); } -static struct xt_target same_reg = { +static struct ipt_target same_reg = { .name = "SAME", - .family = AF_INET, .target = same_target, .targetsize = sizeof(struct ipt_same_info), .table = "nat", @@ -201,12 +199,12 @@ static struct xt_target same_reg = { static int __init ipt_same_init(void) { - return xt_register_target(&same_reg); + return ipt_register_target(&same_reg); } static void __exit ipt_same_fini(void) { - xt_unregister_target(&same_reg); + ipt_unregister_target(&same_reg); } module_init(ipt_same_init); diff --git a/trunk/net/ipv4/netfilter/ipt_TCPMSS.c b/trunk/net/ipv4/netfilter/ipt_TCPMSS.c new file mode 100644 index 000000000000..93eb5c3c1884 --- /dev/null +++ b/trunk/net/ipv4/netfilter/ipt_TCPMSS.c @@ -0,0 +1,207 @@ +/* + * This is a module which is used for setting the MSS option in TCP packets. + * + * Copyright (C) 2000 Marc Boucher + * + * 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. + */ + +#include +#include + +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marc Boucher "); +MODULE_DESCRIPTION("iptables TCP MSS modification module"); + +static inline unsigned int +optlen(const u_int8_t *opt, unsigned int offset) +{ + /* Beware zero-length options: make finite progress */ + if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0) + return 1; + else + return opt[offset+1]; +} + +static unsigned int +ipt_tcpmss_target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const struct xt_target *target, + const void *targinfo) +{ + const struct ipt_tcpmss_info *tcpmssinfo = targinfo; + struct tcphdr *tcph; + struct iphdr *iph; + u_int16_t tcplen, newmss; + __be16 newtotlen, oldval; + unsigned int i; + u_int8_t *opt; + + if (!skb_make_writable(pskb, (*pskb)->len)) + return NF_DROP; + + iph = (*pskb)->nh.iph; + tcplen = (*pskb)->len - iph->ihl*4; + tcph = (void *)iph + iph->ihl*4; + + /* Since it passed flags test in tcp match, we know it is is + not a fragment, and has data >= tcp header length. SYN + packets should not contain data: if they did, then we risk + running over MTU, sending Frag Needed and breaking things + badly. --RR */ + if (tcplen != tcph->doff*4) { + if (net_ratelimit()) + printk(KERN_ERR + "ipt_tcpmss_target: bad length (%d bytes)\n", + (*pskb)->len); + return NF_DROP; + } + + if (tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU) { + if (dst_mtu((*pskb)->dst) <= sizeof(struct iphdr) + + sizeof(struct tcphdr)) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_tcpmss_target: " + "unknown or invalid path-MTU (%d)\n", + dst_mtu((*pskb)->dst)); + return NF_DROP; /* or IPT_CONTINUE ?? */ + } + + newmss = dst_mtu((*pskb)->dst) - sizeof(struct iphdr) - + sizeof(struct tcphdr); + } else + newmss = tcpmssinfo->mss; + + opt = (u_int8_t *)tcph; + for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) { + if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS && + opt[i+1] == TCPOLEN_MSS) { + u_int16_t oldmss; + + oldmss = (opt[i+2] << 8) | opt[i+3]; + + if (tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU && + oldmss <= newmss) + return IPT_CONTINUE; + + opt[i+2] = (newmss & 0xff00) >> 8; + opt[i+3] = (newmss & 0x00ff); + + nf_proto_csum_replace2(&tcph->check, *pskb, + htons(oldmss), htons(newmss), 0); + return IPT_CONTINUE; + } + } + + /* + * MSS Option not found ?! add it.. + */ + if (skb_tailroom((*pskb)) < TCPOLEN_MSS) { + struct sk_buff *newskb; + + newskb = skb_copy_expand(*pskb, skb_headroom(*pskb), + TCPOLEN_MSS, GFP_ATOMIC); + if (!newskb) + return NF_DROP; + kfree_skb(*pskb); + *pskb = newskb; + iph = (*pskb)->nh.iph; + tcph = (void *)iph + iph->ihl*4; + } + + skb_put((*pskb), TCPOLEN_MSS); + + opt = (u_int8_t *)tcph + sizeof(struct tcphdr); + memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); + + nf_proto_csum_replace2(&tcph->check, *pskb, + htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1); + opt[0] = TCPOPT_MSS; + opt[1] = TCPOLEN_MSS; + opt[2] = (newmss & 0xff00) >> 8; + opt[3] = (newmss & 0x00ff); + + nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0); + + oldval = ((__be16 *)tcph)[6]; + tcph->doff += TCPOLEN_MSS/4; + nf_proto_csum_replace2(&tcph->check, *pskb, + oldval, ((__be16 *)tcph)[6], 0); + + newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS); + nf_csum_replace2(&iph->check, iph->tot_len, newtotlen); + iph->tot_len = newtotlen; + return IPT_CONTINUE; +} + +#define TH_SYN 0x02 + +static inline int find_syn_match(const struct ipt_entry_match *m) +{ + const struct ipt_tcp *tcpinfo = (const struct ipt_tcp *)m->data; + + if (strcmp(m->u.kernel.match->name, "tcp") == 0 && + tcpinfo->flg_cmp & TH_SYN && + !(tcpinfo->invflags & IPT_TCP_INV_FLAGS)) + return 1; + + return 0; +} + +/* Must specify -p tcp --syn/--tcp-flags SYN */ +static int +ipt_tcpmss_checkentry(const char *tablename, + const void *e_void, + const struct xt_target *target, + void *targinfo, + unsigned int hook_mask) +{ + const struct ipt_tcpmss_info *tcpmssinfo = targinfo; + const struct ipt_entry *e = e_void; + + if (tcpmssinfo->mss == IPT_TCPMSS_CLAMP_PMTU && + (hook_mask & ~((1 << NF_IP_FORWARD) | + (1 << NF_IP_LOCAL_OUT) | + (1 << NF_IP_POST_ROUTING))) != 0) { + printk("TCPMSS: path-MTU clamping only supported in " + "FORWARD, OUTPUT and POSTROUTING hooks\n"); + return 0; + } + + if (IPT_MATCH_ITERATE(e, find_syn_match)) + return 1; + printk("TCPMSS: Only works on TCP SYN packets\n"); + return 0; +} + +static struct ipt_target ipt_tcpmss_reg = { + .name = "TCPMSS", + .target = ipt_tcpmss_target, + .targetsize = sizeof(struct ipt_tcpmss_info), + .proto = IPPROTO_TCP, + .checkentry = ipt_tcpmss_checkentry, + .me = THIS_MODULE, +}; + +static int __init ipt_tcpmss_init(void) +{ + return ipt_register_target(&ipt_tcpmss_reg); +} + +static void __exit ipt_tcpmss_fini(void) +{ + ipt_unregister_target(&ipt_tcpmss_reg); +} + +module_init(ipt_tcpmss_init); +module_exit(ipt_tcpmss_fini); diff --git a/trunk/net/ipv4/netfilter/ipt_TOS.c b/trunk/net/ipv4/netfilter/ipt_TOS.c index 29b05a6bd108..18e74ac4d425 100644 --- a/trunk/net/ipv4/netfilter/ipt_TOS.c +++ b/trunk/net/ipv4/netfilter/ipt_TOS.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include MODULE_LICENSE("GPL"); @@ -40,7 +40,7 @@ target(struct sk_buff **pskb, iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos)); } - return XT_CONTINUE; + return IPT_CONTINUE; } static int @@ -63,9 +63,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_target ipt_tos_reg = { +static struct ipt_target ipt_tos_reg = { .name = "TOS", - .family = AF_INET, .target = target, .targetsize = sizeof(struct ipt_tos_target_info), .table = "mangle", @@ -75,12 +74,12 @@ static struct xt_target ipt_tos_reg = { static int __init ipt_tos_init(void) { - return xt_register_target(&ipt_tos_reg); + return ipt_register_target(&ipt_tos_reg); } static void __exit ipt_tos_fini(void) { - xt_unregister_target(&ipt_tos_reg); + ipt_unregister_target(&ipt_tos_reg); } module_init(ipt_tos_init); diff --git a/trunk/net/ipv4/netfilter/ipt_TTL.c b/trunk/net/ipv4/netfilter/ipt_TTL.c index d2b6fa3f9dcd..fffe5ca82e91 100644 --- a/trunk/net/ipv4/netfilter/ipt_TTL.c +++ b/trunk/net/ipv4/netfilter/ipt_TTL.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include MODULE_AUTHOR("Harald Welte "); @@ -59,7 +59,7 @@ ipt_ttl_target(struct sk_buff **pskb, iph->ttl = new_ttl; } - return XT_CONTINUE; + return IPT_CONTINUE; } static int ipt_ttl_checkentry(const char *tablename, @@ -80,9 +80,8 @@ static int ipt_ttl_checkentry(const char *tablename, return 1; } -static struct xt_target ipt_TTL = { +static struct ipt_target ipt_TTL = { .name = "TTL", - .family = AF_INET, .target = ipt_ttl_target, .targetsize = sizeof(struct ipt_TTL_info), .table = "mangle", @@ -92,12 +91,12 @@ static struct xt_target ipt_TTL = { static int __init ipt_ttl_init(void) { - return xt_register_target(&ipt_TTL); + return ipt_register_target(&ipt_TTL); } static void __exit ipt_ttl_fini(void) { - xt_unregister_target(&ipt_TTL); + ipt_unregister_target(&ipt_TTL); } module_init(ipt_ttl_init); diff --git a/trunk/net/ipv4/netfilter/ipt_ULOG.c b/trunk/net/ipv4/netfilter/ipt_ULOG.c index 7af57a3a1f36..dbd34783a64d 100644 --- a/trunk/net/ipv4/netfilter/ipt_ULOG.c +++ b/trunk/net/ipv4/netfilter/ipt_ULOG.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include #include @@ -132,6 +132,7 @@ static void ulog_send(unsigned int nlgroupnum) ub->qlen = 0; ub->skb = NULL; ub->lastnlh = NULL; + } @@ -313,7 +314,7 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb, ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL); - return XT_CONTINUE; + return IPT_CONTINUE; } static void ipt_logfn(unsigned int pf, @@ -362,9 +363,8 @@ static int ipt_ulog_checkentry(const char *tablename, return 1; } -static struct xt_target ipt_ulog_reg = { +static struct ipt_target ipt_ulog_reg = { .name = "ULOG", - .family = AF_INET, .target = ipt_ulog_target, .targetsize = sizeof(struct ipt_ulog_info), .checkentry = ipt_ulog_checkentry, @@ -379,7 +379,7 @@ static struct nf_logger ipt_ulog_logger = { static int __init ipt_ulog_init(void) { - int ret, i; + int i; DEBUGP("ipt_ULOG: init module\n"); @@ -400,10 +400,9 @@ static int __init ipt_ulog_init(void) if (!nflognl) return -ENOMEM; - ret = xt_register_target(&ipt_ulog_reg); - if (ret < 0) { + if (ipt_register_target(&ipt_ulog_reg) != 0) { sock_release(nflognl->sk_socket); - return ret; + return -EINVAL; } if (nflog) nf_log_register(PF_INET, &ipt_ulog_logger); @@ -420,7 +419,7 @@ static void __exit ipt_ulog_fini(void) if (nflog) nf_log_unregister_logger(&ipt_ulog_logger); - xt_unregister_target(&ipt_ulog_reg); + ipt_unregister_target(&ipt_ulog_reg); sock_release(nflognl->sk_socket); /* remove pending timers and free allocated skb's */ @@ -436,6 +435,7 @@ static void __exit ipt_ulog_fini(void) ub->skb = NULL; } } + } module_init(ipt_ulog_init); diff --git a/trunk/net/ipv4/netfilter/ipt_addrtype.c b/trunk/net/ipv4/netfilter/ipt_addrtype.c index 648f555c4d16..7b60eb74788b 100644 --- a/trunk/net/ipv4/netfilter/ipt_addrtype.c +++ b/trunk/net/ipv4/netfilter/ipt_addrtype.c @@ -16,7 +16,7 @@ #include #include -#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy "); @@ -44,9 +44,8 @@ static int match(const struct sk_buff *skb, return ret; } -static struct xt_match addrtype_match = { +static struct ipt_match addrtype_match = { .name = "addrtype", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_addrtype_info), .me = THIS_MODULE @@ -54,12 +53,12 @@ static struct xt_match addrtype_match = { static int __init ipt_addrtype_init(void) { - return xt_register_match(&addrtype_match); + return ipt_register_match(&addrtype_match); } static void __exit ipt_addrtype_fini(void) { - xt_unregister_match(&addrtype_match); + ipt_unregister_match(&addrtype_match); } module_init(ipt_addrtype_init); diff --git a/trunk/net/ipv4/netfilter/ipt_ah.c b/trunk/net/ipv4/netfilter/ipt_ah.c index 42f41224a43a..1798f86bc534 100644 --- a/trunk/net/ipv4/netfilter/ipt_ah.c +++ b/trunk/net/ipv4/netfilter/ipt_ah.c @@ -6,13 +6,12 @@ * published by the Free Software Foundation. */ -#include #include #include #include #include -#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yon Uriarte "); @@ -87,9 +86,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match ah_match = { +static struct ipt_match ah_match = { .name = "ah", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_ah), .proto = IPPROTO_AH, @@ -99,12 +97,12 @@ static struct xt_match ah_match = { static int __init ipt_ah_init(void) { - return xt_register_match(&ah_match); + return ipt_register_match(&ah_match); } static void __exit ipt_ah_fini(void) { - xt_unregister_match(&ah_match); + ipt_unregister_match(&ah_match); } module_init(ipt_ah_init); diff --git a/trunk/net/ipv4/netfilter/ipt_ecn.c b/trunk/net/ipv4/netfilter/ipt_ecn.c index 37508b2cfea6..dafbdec0efc0 100644 --- a/trunk/net/ipv4/netfilter/ipt_ecn.c +++ b/trunk/net/ipv4/netfilter/ipt_ecn.c @@ -9,13 +9,10 @@ * published by the Free Software Foundation. */ -#include -#include #include #include #include -#include #include #include @@ -112,9 +109,8 @@ static int checkentry(const char *tablename, const void *ip_void, return 1; } -static struct xt_match ecn_match = { +static struct ipt_match ecn_match = { .name = "ecn", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_ecn_info), .checkentry = checkentry, @@ -123,12 +119,12 @@ static struct xt_match ecn_match = { static int __init ipt_ecn_init(void) { - return xt_register_match(&ecn_match); + return ipt_register_match(&ecn_match); } static void __exit ipt_ecn_fini(void) { - xt_unregister_match(&ecn_match); + ipt_unregister_match(&ecn_match); } module_init(ipt_ecn_init); diff --git a/trunk/net/ipv4/netfilter/ipt_iprange.c b/trunk/net/ipv4/netfilter/ipt_iprange.c index 05de593be94c..5202edd8d333 100644 --- a/trunk/net/ipv4/netfilter/ipt_iprange.c +++ b/trunk/net/ipv4/netfilter/ipt_iprange.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include MODULE_LICENSE("GPL"); @@ -63,22 +63,22 @@ match(const struct sk_buff *skb, return 1; } -static struct xt_match iprange_match = { +static struct ipt_match iprange_match = { .name = "iprange", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_iprange_info), + .destroy = NULL, .me = THIS_MODULE }; static int __init ipt_iprange_init(void) { - return xt_register_match(&iprange_match); + return ipt_register_match(&iprange_match); } static void __exit ipt_iprange_fini(void) { - xt_unregister_match(&iprange_match); + ipt_unregister_match(&iprange_match); } module_init(ipt_iprange_init); diff --git a/trunk/net/ipv4/netfilter/ipt_owner.c b/trunk/net/ipv4/netfilter/ipt_owner.c index 9f496ac834b5..78c336f12a9e 100644 --- a/trunk/net/ipv4/netfilter/ipt_owner.c +++ b/trunk/net/ipv4/netfilter/ipt_owner.c @@ -15,7 +15,7 @@ #include #include -#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher "); @@ -68,9 +68,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match owner_match = { +static struct ipt_match owner_match = { .name = "owner", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_owner_info), .hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING), @@ -80,12 +79,12 @@ static struct xt_match owner_match = { static int __init ipt_owner_init(void) { - return xt_register_match(&owner_match); + return ipt_register_match(&owner_match); } static void __exit ipt_owner_fini(void) { - xt_unregister_match(&owner_match); + ipt_unregister_match(&owner_match); } module_init(ipt_owner_init); diff --git a/trunk/net/ipv4/netfilter/ipt_recent.c b/trunk/net/ipv4/netfilter/ipt_recent.c index 6b97b6796173..4db0e73c56f1 100644 --- a/trunk/net/ipv4/netfilter/ipt_recent.c +++ b/trunk/net/ipv4/netfilter/ipt_recent.c @@ -12,7 +12,6 @@ * Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org */ #include -#include #include #include #include @@ -25,7 +24,7 @@ #include #include -#include +#include #include MODULE_AUTHOR("Patrick McHardy "); @@ -463,9 +462,8 @@ static struct file_operations recent_fops = { }; #endif /* CONFIG_PROC_FS */ -static struct xt_match recent_match = { +static struct ipt_match recent_match = { .name = "recent", - .family = AF_INET, .match = ipt_recent_match, .matchsize = sizeof(struct ipt_recent_info), .checkentry = ipt_recent_checkentry, @@ -481,13 +479,13 @@ static int __init ipt_recent_init(void) return -EINVAL; ip_list_hash_size = 1 << fls(ip_list_tot); - err = xt_register_match(&recent_match); + err = ipt_register_match(&recent_match); #ifdef CONFIG_PROC_FS if (err) return err; proc_dir = proc_mkdir("ipt_recent", proc_net); if (proc_dir == NULL) { - xt_unregister_match(&recent_match); + ipt_unregister_match(&recent_match); err = -ENOMEM; } #endif @@ -497,7 +495,7 @@ static int __init ipt_recent_init(void) static void __exit ipt_recent_exit(void) { BUG_ON(!list_empty(&tables)); - xt_unregister_match(&recent_match); + ipt_unregister_match(&recent_match); #ifdef CONFIG_PROC_FS remove_proc_entry("ipt_recent", proc_net); #endif diff --git a/trunk/net/ipv4/netfilter/ipt_tos.c b/trunk/net/ipv4/netfilter/ipt_tos.c index 5d33b51d49d8..5549c39c7851 100644 --- a/trunk/net/ipv4/netfilter/ipt_tos.c +++ b/trunk/net/ipv4/netfilter/ipt_tos.c @@ -8,12 +8,11 @@ * published by the Free Software Foundation. */ -#include #include #include #include -#include +#include MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("iptables TOS match module"); @@ -33,9 +32,8 @@ match(const struct sk_buff *skb, return (skb->nh.iph->tos == info->tos) ^ info->invert; } -static struct xt_match tos_match = { +static struct ipt_match tos_match = { .name = "tos", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_tos_info), .me = THIS_MODULE, @@ -43,12 +41,12 @@ static struct xt_match tos_match = { static int __init ipt_multiport_init(void) { - return xt_register_match(&tos_match); + return ipt_register_match(&tos_match); } static void __exit ipt_multiport_fini(void) { - xt_unregister_match(&tos_match); + ipt_unregister_match(&tos_match); } module_init(ipt_multiport_init); diff --git a/trunk/net/ipv4/netfilter/ipt_ttl.c b/trunk/net/ipv4/netfilter/ipt_ttl.c index d5cd984e5ed2..a5243bdb87d7 100644 --- a/trunk/net/ipv4/netfilter/ipt_ttl.c +++ b/trunk/net/ipv4/netfilter/ipt_ttl.c @@ -9,12 +9,11 @@ * published by the Free Software Foundation. */ -#include #include #include #include -#include +#include MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("IP tables TTL matching module"); @@ -49,9 +48,8 @@ static int match(const struct sk_buff *skb, return 0; } -static struct xt_match ttl_match = { +static struct ipt_match ttl_match = { .name = "ttl", - .family = AF_INET, .match = match, .matchsize = sizeof(struct ipt_ttl_info), .me = THIS_MODULE, @@ -59,12 +57,13 @@ static struct xt_match ttl_match = { static int __init ipt_ttl_init(void) { - return xt_register_match(&ttl_match); + return ipt_register_match(&ttl_match); } static void __exit ipt_ttl_fini(void) { - xt_unregister_match(&ttl_match); + ipt_unregister_match(&ttl_match); + } module_init(ipt_ttl_init); diff --git a/trunk/net/ipv4/netfilter/iptable_filter.c b/trunk/net/ipv4/netfilter/iptable_filter.c index 51053cb42f43..e2e7dd8d7903 100644 --- a/trunk/net/ipv4/netfilter/iptable_filter.c +++ b/trunk/net/ipv4/netfilter/iptable_filter.c @@ -74,7 +74,7 @@ static struct } }; -static struct xt_table packet_filter = { +static struct ipt_table packet_filter = { .name = "filter", .valid_hooks = FILTER_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, diff --git a/trunk/net/ipv4/netfilter/iptable_mangle.c b/trunk/net/ipv4/netfilter/iptable_mangle.c index a532e4d84332..af2939889444 100644 --- a/trunk/net/ipv4/netfilter/iptable_mangle.c +++ b/trunk/net/ipv4/netfilter/iptable_mangle.c @@ -103,7 +103,7 @@ static struct } }; -static struct xt_table packet_mangler = { +static struct ipt_table packet_mangler = { .name = "mangle", .valid_hooks = MANGLE_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, diff --git a/trunk/net/ipv4/netfilter/iptable_raw.c b/trunk/net/ipv4/netfilter/iptable_raw.c index 5277550fa6b5..bcbeb4aeacd9 100644 --- a/trunk/net/ipv4/netfilter/iptable_raw.c +++ b/trunk/net/ipv4/netfilter/iptable_raw.c @@ -79,7 +79,7 @@ static struct } }; -static struct xt_table packet_raw = { +static struct ipt_table packet_raw = { .name = "raw", .valid_hooks = RAW_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, diff --git a/trunk/net/ipv4/netfilter/nf_nat_core.c b/trunk/net/ipv4/netfilter/nf_nat_core.c index 998b2557692c..86a92272b053 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_core.c +++ b/trunk/net/ipv4/netfilter/nf_nat_core.c @@ -254,9 +254,8 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, if (maniptype == IP_NAT_MANIP_SRC) { if (find_appropriate_src(orig_tuple, tuple, range)) { DEBUGP("get_unique_tuple: Found current src map\n"); - if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) - if (!nf_nat_used_tuple(tuple, ct)) - return; + if (!nf_nat_used_tuple(tuple, ct)) + return; } } @@ -270,13 +269,6 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, proto = nf_nat_proto_find_get(orig_tuple->dst.protonum); - /* Change protocol info to have some randomization */ - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) { - proto->unique_tuple(tuple, range, maniptype, ct); - nf_nat_proto_put(proto); - return; - } - /* Only bother mapping if it's not already in range and unique */ if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || proto->in_range(tuple, maniptype, &range->min, &range->max)) && diff --git a/trunk/net/ipv4/netfilter/nf_nat_helper.c b/trunk/net/ipv4/netfilter/nf_nat_helper.c index dc6738bdfab7..98fbfc84d183 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_helper.c +++ b/trunk/net/ipv4/netfilter/nf_nat_helper.c @@ -176,7 +176,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb, datalen = (*pskb)->len - iph->ihl*4; if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) { tcph->check = 0; - tcph->check = tcp_v4_check(datalen, + tcph->check = tcp_v4_check(tcph, datalen, iph->saddr, iph->daddr, csum_partial((char *)tcph, datalen, 0)); diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c index 439164c7a626..7e26a7e9bee1 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_tcp.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -76,9 +75,6 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple, range_size = ntohs(range->max.tcp.port) - min + 1; } - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) - port = net_random(); - for (i = 0; i < range_size; i++, port++) { *portptr = htons(min + port % range_size); if (!nf_nat_used_tuple(tuple, ct)) diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c index 8cae6e063bb6..ab0ce4c8699f 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_udp.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -74,9 +73,6 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple, range_size = ntohs(range->max.udp.port) - min + 1; } - if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) - port = net_random(); - for (i = 0; i < range_size; i++, port++) { *portptr = htons(min + port % range_size); if (!nf_nat_used_tuple(tuple, ct)) diff --git a/trunk/net/ipv4/netfilter/nf_nat_rule.c b/trunk/net/ipv4/netfilter/nf_nat_rule.c index 7f95b4e2eb31..b868ee0195d4 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_rule.c +++ b/trunk/net/ipv4/netfilter/nf_nat_rule.c @@ -119,7 +119,7 @@ static struct } }; -static struct xt_table nat_table = { +static struct ipt_table nat_table = { .name = "nat", .valid_hooks = NAT_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, @@ -226,10 +226,6 @@ static int ipt_dnat_checkentry(const char *tablename, printk("DNAT: multiple ranges no longer supported\n"); return 0; } - if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM) { - printk("DNAT: port randomization not supported\n"); - return 0; - } return 1; } @@ -294,7 +290,7 @@ int nf_nat_rule_find(struct sk_buff **pskb, return ret; } -static struct xt_target ipt_snat_reg = { +static struct ipt_target ipt_snat_reg = { .name = "SNAT", .target = ipt_snat_target, .targetsize = sizeof(struct nf_nat_multi_range_compat), diff --git a/trunk/net/ipv4/netfilter/nf_nat_standalone.c b/trunk/net/ipv4/netfilter/nf_nat_standalone.c index 5a964a167c13..00d6dea9f7f3 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_standalone.c +++ b/trunk/net/ipv4/netfilter/nf_nat_standalone.c @@ -32,6 +32,12 @@ #define DEBUGP(format, args...) #endif +#define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \ + : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \ + : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT" \ + : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \ + : "*ERROR*"))) + #ifdef CONFIG_XFRM static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) { diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index fed6a1e7af9e..a6c63bbd9ddb 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -489,7 +489,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(&rt, &fl, sk, 1); + err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); } if (err) goto done; diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index baee304a3cb7..2daa0dc19d33 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -2635,7 +2635,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; r = nlmsg_data(nlh); r->rtm_family = AF_INET; @@ -2718,8 +2718,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 5bd43d7294fd..b67e0dd743be 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -2415,11 +2415,10 @@ void __init tcp_init(void) &tcp_hashinfo.ehash_size, NULL, 0); - tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size; - for (i = 0; i < tcp_hashinfo.ehash_size; i++) { + tcp_hashinfo.ehash_size = (1 << tcp_hashinfo.ehash_size) >> 1; + for (i = 0; i < (tcp_hashinfo.ehash_size << 1); i++) { rwlock_init(&tcp_hashinfo.ehash[i].lock); INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain); - INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain); } tcp_hashinfo.bhash = @@ -2476,7 +2475,7 @@ void __init tcp_init(void) printk(KERN_INFO "TCP: Hash tables configured " "(established %d bind %d)\n", - tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size); + tcp_hashinfo.ehash_size << 1, tcp_hashinfo.bhash_size); tcp_register_congestion_control(&tcp_reno); } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index c6109895bb5e..c26076fb890e 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -936,58 +936,28 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ struct tcp_sock *tp = tcp_sk(sk); unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked; struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2); - struct sk_buff *cached_skb; int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3; int reord = tp->packets_out; int prior_fackets; u32 lost_retrans = 0; int flag = 0; int dup_sack = 0; - int cached_fack_count; int i; - int first_sack_index; if (!tp->sacked_out) tp->fackets_out = 0; prior_fackets = tp->fackets_out; - /* Check for D-SACK. */ - if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { - dup_sack = 1; - tp->rx_opt.sack_ok |= 4; - NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); - } else if (num_sacks > 1 && - !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && - !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { - dup_sack = 1; - tp->rx_opt.sack_ok |= 4; - NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); - } - - /* D-SACK for already forgotten data... - * Do dumb counting. */ - if (dup_sack && - !after(ntohl(sp[0].end_seq), prior_snd_una) && - after(ntohl(sp[0].end_seq), tp->undo_marker)) - tp->undo_retrans--; - - /* Eliminate too old ACKs, but take into - * account more or less fresh ones, they can - * contain valid SACK info. - */ - if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window)) - return 0; - /* SACK fastpath: * if the only SACK change is the increase of the end_seq of * the first block then only apply that SACK block * and use retrans queue hinting otherwise slowpath */ flag = 1; - for (i = 0; i < num_sacks; i++) { - __be32 start_seq = sp[i].start_seq; - __be32 end_seq = sp[i].end_seq; + for (i = 0; i< num_sacks; i++) { + __u32 start_seq = ntohl(sp[i].start_seq); + __u32 end_seq = ntohl(sp[i].end_seq); - if (i == 0) { + if (i == 0){ if (tp->recv_sack_cache[i].start_seq != start_seq) flag = 0; } else { @@ -997,14 +967,39 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } tp->recv_sack_cache[i].start_seq = start_seq; tp->recv_sack_cache[i].end_seq = end_seq; - } - /* Clear the rest of the cache sack blocks so they won't match mistakenly. */ - for (; i < ARRAY_SIZE(tp->recv_sack_cache); i++) { - tp->recv_sack_cache[i].start_seq = 0; - tp->recv_sack_cache[i].end_seq = 0; + + /* Check for D-SACK. */ + if (i == 0) { + u32 ack = TCP_SKB_CB(ack_skb)->ack_seq; + + if (before(start_seq, ack)) { + dup_sack = 1; + tp->rx_opt.sack_ok |= 4; + NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); + } else if (num_sacks > 1 && + !after(end_seq, ntohl(sp[1].end_seq)) && + !before(start_seq, ntohl(sp[1].start_seq))) { + dup_sack = 1; + tp->rx_opt.sack_ok |= 4; + NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); + } + + /* D-SACK for already forgotten data... + * Do dumb counting. */ + if (dup_sack && + !after(end_seq, prior_snd_una) && + after(end_seq, tp->undo_marker)) + tp->undo_retrans--; + + /* Eliminate too old ACKs, but take into + * account more or less fresh ones, they can + * contain valid SACK info. + */ + if (before(ack, prior_snd_una - tp->max_window)) + return 0; + } } - first_sack_index = 0; if (flag) num_sacks = 1; else { @@ -1021,10 +1016,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ tmp = sp[j]; sp[j] = sp[j+1]; sp[j+1] = tmp; - - /* Track where the first SACK block goes to */ - if (j == first_sack_index) - first_sack_index = j+1; } } @@ -1034,22 +1025,20 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ /* clear flag as used for different purpose in following code */ flag = 0; - /* Use SACK fastpath hint if valid */ - cached_skb = tp->fastpath_skb_hint; - cached_fack_count = tp->fastpath_cnt_hint; - if (!cached_skb) { - cached_skb = sk->sk_write_queue.next; - cached_fack_count = 0; - } - for (i=0; istart_seq); __u32 end_seq = ntohl(sp->end_seq); int fack_count; - skb = cached_skb; - fack_count = cached_fack_count; + /* Use SACK fastpath hint if valid */ + if (tp->fastpath_skb_hint) { + skb = tp->fastpath_skb_hint; + fack_count = tp->fastpath_cnt_hint; + } else { + skb = sk->sk_write_queue.next; + fack_count = 0; + } /* Event "B" in the comment above. */ if (after(end_seq, tp->high_seq)) @@ -1059,12 +1048,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int in_sack, pcount; u8 sacked; - cached_skb = skb; - cached_fack_count = fack_count; - if (i == first_sack_index) { - tp->fastpath_skb_hint = skb; - tp->fastpath_cnt_hint = fack_count; - } + tp->fastpath_skb_hint = skb; + tp->fastpath_cnt_hint = fack_count; /* The retransmission queue is always in order, so * we can short-circuit the walk early. diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index f51d6404c61c..12de90a5047c 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -191,7 +191,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) tmp = ip_route_connect(&rt, nexthop, inet->saddr, RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, IPPROTO_TCP, - inet->sport, usin->sin_port, sk, 1); + inet->sport, usin->sin_port, sk); if (tmp < 0) return tmp; @@ -502,11 +502,11 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) struct tcphdr *th = skb->h.th; if (skb->ip_summed == CHECKSUM_PARTIAL) { - th->check = ~tcp_v4_check(len, inet->saddr, - inet->daddr, 0); + th->check = ~tcp_v4_check(th, len, + inet->saddr, inet->daddr, 0); skb->csum_offset = offsetof(struct tcphdr, check); } else { - th->check = tcp_v4_check(len, inet->saddr, inet->daddr, + th->check = tcp_v4_check(th, len, inet->saddr, inet->daddr, csum_partial((char *)th, th->doff << 2, skb->csum)); @@ -525,7 +525,7 @@ int tcp_v4_gso_send_check(struct sk_buff *skb) th = skb->h.th; th->check = 0; - th->check = ~tcp_v4_check(skb->len, iph->saddr, iph->daddr, 0); + th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0); skb->csum_offset = offsetof(struct tcphdr, check); skb->ip_summed = CHECKSUM_PARTIAL; return 0; @@ -747,7 +747,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req, if (skb) { struct tcphdr *th = skb->h.th; - th->check = tcp_v4_check(skb->len, + th->check = tcp_v4_check(th, skb->len, ireq->loc_addr, ireq->rmt_addr, csum_partial((char *)th, skb->len, @@ -1514,7 +1514,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) static __sum16 tcp_v4_checksum_init(struct sk_buff *skb) { if (skb->ip_summed == CHECKSUM_COMPLETE) { - if (!tcp_v4_check(skb->len, skb->nh.iph->saddr, + if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr, skb->nh.iph->daddr, skb->csum)) { skb->ip_summed = CHECKSUM_UNNECESSARY; return 0; @@ -2051,7 +2051,7 @@ static void *established_get_first(struct seq_file *seq) } st->state = TCP_SEQ_STATE_TIME_WAIT; inet_twsk_for_each(tw, node, - &tcp_hashinfo.ehash[st->bucket].twchain) { + &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) { if (tw->tw_family != st->family) { continue; } @@ -2107,7 +2107,7 @@ static void *established_get_next(struct seq_file *seq, void *cur) } st->state = TCP_SEQ_STATE_TIME_WAIT; - tw = tw_head(&tcp_hashinfo.ehash[st->bucket].twchain); + tw = tw_head(&tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain); goto get_tw; found: cur = sk; diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 58b7111523f4..975f4472af29 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -965,8 +965,7 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *sk u32 in_flight, cwnd; /* Don't be strict about the congestion window for the final FIN. */ - if ((TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && - tcp_skb_pcount(skb) == 1) + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) return 1; in_flight = tcp_packets_in_flight(tp); diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 8b54c68a0d12..cfff930f2baf 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -629,7 +629,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, { .sport = inet->sport, .dport = dport } } }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(&rt, &fl, sk, 1); + err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); if (err) goto out; diff --git a/trunk/net/ipv4/xfrm4_mode_tunnel.c b/trunk/net/ipv4/xfrm4_mode_tunnel.c index e54c5494c88f..e23c21d31a53 100644 --- a/trunk/net/ipv4/xfrm4_mode_tunnel.c +++ b/trunk/net/ipv4/xfrm4_mode_tunnel.c @@ -23,12 +23,6 @@ static inline void ipip_ecn_decapsulate(struct sk_buff *skb) IP_ECN_set_ce(inner_iph); } -static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) -{ - if (INET_ECN_is_ce(iph->tos)) - IP6_ECN_set_ce(skb->nh.ipv6h); -} - /* Add encapsulation header. * * The top IP header will be constructed per RFC 2401. The following fields @@ -42,7 +36,6 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb) static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { struct dst_entry *dst = skb->dst; - struct xfrm_dst *xdst = (struct xfrm_dst*)dst; struct iphdr *iph, *top_iph; int flags; @@ -55,27 +48,15 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->ihl = 5; top_iph->version = 4; - flags = x->props.flags; - /* DS disclosed */ - if (xdst->route->ops->family == AF_INET) { - top_iph->protocol = IPPROTO_IPIP; - top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos); - top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? - 0 : (iph->frag_off & htons(IP_DF)); - } -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) - else { - struct ipv6hdr *ipv6h = (struct ipv6hdr*)iph; - top_iph->protocol = IPPROTO_IPV6; - top_iph->tos = INET_ECN_encapsulate(iph->tos, ipv6_get_dsfield(ipv6h)); - top_iph->frag_off = 0; - } -#endif + top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos); + flags = x->props.flags; if (flags & XFRM_STATE_NOECN) IP_ECN_clear(top_iph); + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (iph->frag_off & htons(IP_DF)); if (!top_iph->frag_off) __ip_select_ident(top_iph, dst->child, 0); @@ -83,6 +64,7 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->saddr = x->props.saddr.a4; top_iph->daddr = x->id.daddr.a4; + top_iph->protocol = IPPROTO_IPIP; memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); return 0; @@ -93,16 +75,8 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; int err = -EINVAL; - switch(iph->protocol){ - case IPPROTO_IPIP: -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) - case IPPROTO_IPV6: - break; -#endif - default: - goto out; - } - + if (iph->protocol != IPPROTO_IPIP) + goto out; if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto out; @@ -110,19 +84,10 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) goto out; - if (iph->protocol == IPPROTO_IPIP) { - if (x->props.flags & XFRM_STATE_DECAP_DSCP) - ipv4_copy_dscp(iph, skb->h.ipiph); - if (!(x->props.flags & XFRM_STATE_NOECN)) - ipip_ecn_decapsulate(skb); - } -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) - else { - if (!(x->props.flags & XFRM_STATE_NOECN)) - ipip6_ecn_decapsulate(iph, skb); - skb->protocol = htons(ETH_P_IPV6); - } -#endif + if (x->props.flags & XFRM_STATE_DECAP_DSCP) + ipv4_copy_dscp(iph, skb->h.ipiph); + if (!(x->props.flags & XFRM_STATE_NOECN)) + ipip_ecn_decapsulate(skb); skb->mac.raw = memmove(skb->data - skb->mac_len, skb->mac.raw, skb->mac_len); skb->nh.raw = skb->data; diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index 699f27ce62ad..fb9f69c616f5 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -72,11 +72,13 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int struct dst_entry *dst, *dst_prev; struct rtable *rt0 = (struct rtable*)(*dst_p); struct rtable *rt = rt0; + __be32 remote = fl->fl4_dst; + __be32 local = fl->fl4_src; struct flowi fl_tunnel = { .nl_u = { .ip4_u = { - .saddr = fl->fl4_src, - .daddr = fl->fl4_dst, + .saddr = local, + .daddr = remote, .tos = fl->fl4_tos } } @@ -92,6 +94,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int for (i = 0; i < nx; i++) { struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops); struct xfrm_dst *xdst; + int tunnel = 0; if (unlikely(dst1 == NULL)) { err = -ENOBUFS; @@ -113,28 +116,19 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int dst1->next = dst_prev; dst_prev = dst1; - + if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { + remote = xfrm[i]->id.daddr.a4; + local = xfrm[i]->props.saddr.a4; + tunnel = 1; + } header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; - if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) { - unsigned short encap_family = xfrm[i]->props.family; - switch(encap_family) { - case AF_INET: - fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4; - fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4; - break; -#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) - case AF_INET6: - ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr*)&xfrm[i]->id.daddr.a6); - ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr*)&xfrm[i]->props.saddr.a6); - break; -#endif - default: - BUG_ON(1); - } + if (tunnel) { + fl_tunnel.fl4_src = local; + fl_tunnel.fl4_dst = remote; err = xfrm_dst_lookup((struct xfrm_dst **)&rt, - &fl_tunnel, encap_family); + &fl_tunnel, AF_INET); if (err) goto error; } else @@ -151,7 +145,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int i = 0; for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; - struct xfrm_state_afinfo *afinfo; x->u.rt.fl = *fl; dst_prev->xfrm = xfrm[i++]; @@ -169,18 +162,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int /* Copy neighbout for reachability confirmation */ dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); dst_prev->input = rt->u.dst.input; - /* XXX: When IPv6 module can be unloaded, we should manage reference - * to xfrm6_output in afinfo->output. Miyazawa - * */ - afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); - if (!afinfo) { - dst = *dst_p; - err = -EAFNOSUPPORT; - goto error; - } - dst_prev->output = afinfo->output; - xfrm_state_put_afinfo(afinfo); - if (dst_prev->xfrm->props.family == AF_INET && rt->peer) + dst_prev->output = xfrm4_output; + if (rt->peer) atomic_inc(&rt->peer->refcnt); x->u.rt.peer = rt->peer; /* Sheit... I remember I did this right. Apparently, @@ -291,7 +274,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) if (likely(xdst->u.rt.idev)) in_dev_put(xdst->u.rt.idev); - if (dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer)) + if (likely(xdst->u.rt.peer)) inet_putpeer(xdst->u.rt.peer); xfrm_dst_destroy(xdst); } diff --git a/trunk/net/ipv4/xfrm4_state.c b/trunk/net/ipv4/xfrm4_state.c index 93e2c061cdda..3cc3df0c6ece 100644 --- a/trunk/net/ipv4/xfrm4_state.c +++ b/trunk/net/ipv4/xfrm4_state.c @@ -51,7 +51,6 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { .family = AF_INET, .init_flags = xfrm4_init_flags, .init_tempsel = __xfrm4_init_tempsel, - .output = xfrm4_output, }; void __init xfrm4_state_init(void) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index fe5e1d833871..e3854696988d 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -3117,7 +3117,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), ifa->idev->dev->ifindex); @@ -3137,10 +3137,8 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, } if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 || - put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) { - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; - } + put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) + return nlmsg_cancel(skb, nlh); return nlmsg_end(skb, nlh); } @@ -3157,15 +3155,13 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); if (nla_put(skb, IFA_MULTICAST, 16, &ifmca->mca_addr) < 0 || put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp, - INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) { - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; - } + INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) + return nlmsg_cancel(skb, nlh); return nlmsg_end(skb, nlh); } @@ -3182,15 +3178,13 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); if (nla_put(skb, IFA_ANYCAST, 16, &ifaca->aca_addr) < 0 || put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp, - INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) { - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; - } + INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) + return nlmsg_cancel(skb, nlh); return nlmsg_end(skb, nlh); } @@ -3340,12 +3334,9 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWADDR, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout_ifa; - } + /* failure implies BUG in inet6_ifaddr_msgsize() */ + BUG_ON(err < 0); + err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); errout_ifa: in6_ifa_put(ifa); @@ -3363,12 +3354,9 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) goto errout; err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in inet6_ifaddr_msgsize() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); errout: if (err < 0) @@ -3438,7 +3426,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; hdr = nlmsg_data(nlh); hdr->ifi_family = AF_INET6; @@ -3481,8 +3469,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) @@ -3520,12 +3507,9 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) goto errout; err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in inet6_if_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in inet6_if_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); errout: if (err < 0) @@ -3549,7 +3533,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; pmsg = nlmsg_data(nlh); pmsg->prefix_family = AF_INET6; @@ -3574,8 +3558,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } static void inet6_prefix_notify(int event, struct inet6_dev *idev, @@ -3589,12 +3572,9 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, goto errout; err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in inet6_prefix_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in inet6_prefix_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); errout: if (err < 0) diff --git a/trunk/net/ipv6/datagram.c b/trunk/net/ipv6/datagram.c index ecde30140f4a..5c94fea90e97 100644 --- a/trunk/net/ipv6/datagram.c +++ b/trunk/net/ipv6/datagram.c @@ -178,7 +178,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) goto out; /* source address lookup done in ip6_dst_lookup */ diff --git a/trunk/net/ipv6/inet6_hashtables.c b/trunk/net/ipv6/inet6_hashtables.c index e61116949bee..b7e5bae0e347 100644 --- a/trunk/net/ipv6/inet6_hashtables.c +++ b/trunk/net/ipv6/inet6_hashtables.c @@ -79,7 +79,7 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, goto hit; /* You sunk my battleship! */ } /* Must check for a TIME_WAIT'er before going to listener hash. */ - sk_for_each(sk, node, &head->twchain) { + sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) { const struct inet_timewait_sock *tw = inet_twsk(sk); if(*((__portpair *)&(tw->tw_dport)) == ports && @@ -183,7 +183,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, write_lock(&head->lock); /* Check TIME-WAIT sockets first. */ - sk_for_each(sk2, node, &head->twchain) { + sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2); tw = inet_twsk(sk2); diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index 2b9e3bb7da65..8d918348f5bb 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -999,8 +999,7 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) break; dev = t->dev; } - err = 0; - unregister_netdevice(dev); + err = unregister_netdevice(dev); break; default: err = -EINVAL; diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index e3ec21695832..882cde4b4047 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -1582,8 +1582,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, skb = add_grhead(skb, pmc, type, &pgr); first = 0; } - if (!skb) - return NULL; psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc)); *psrc = psf->sf_addr; scount++; stotal++; diff --git a/trunk/net/ipv6/mip6.c b/trunk/net/ipv6/mip6.c index 681bb077eacc..be7dd7db65d7 100644 --- a/trunk/net/ipv6/mip6.c +++ b/trunk/net/ipv6/mip6.c @@ -89,6 +89,7 @@ static int mip6_mh_len(int type) int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) { struct ip6_mh *mh; + int mhlen; if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) || !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3))) @@ -102,6 +103,31 @@ int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw); return -1; } + mhlen = (mh->ip6mh_hdrlen + 1) << 3; + + if (skb->ip_summed == CHECKSUM_COMPLETE) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + mhlen, IPPROTO_MH, + skb->csum)) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH hw checksum failed\n"); + skb->ip_summed = CHECKSUM_NONE; + } + } + if (skb->ip_summed == CHECKSUM_NONE) { + if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + mhlen, IPPROTO_MH, + skb_checksum(skb, 0, mhlen, 0))) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed " + "[" NIP6_FMT " > " NIP6_FMT "]\n", + NIP6(skb->nh.ipv6h->saddr), + NIP6(skb->nh.ipv6h->daddr)); + return -1; + } + skb->ip_summed = CHECKSUM_UNNECESSARY; + } if (mh->ip6mh_proto != IPPROTO_NONE) { LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", diff --git a/trunk/net/ipv6/netfilter/Kconfig b/trunk/net/ipv6/netfilter/Kconfig index cd549aea84f0..adcd6131df2a 100644 --- a/trunk/net/ipv6/netfilter/Kconfig +++ b/trunk/net/ipv6/netfilter/Kconfig @@ -114,14 +114,6 @@ config IP6_NF_MATCH_AH To compile it as a module, choose M here. If unsure, say N. -config IP6_NF_MATCH_MH - tristate "MH match support" - depends on IP6_NF_IPTABLES - help - This module allows one to match MH packets. - - To compile it as a module, choose M here. If unsure, say N. - config IP6_NF_MATCH_EUI64 tristate "EUI64 address check" depends on IP6_NF_IPTABLES diff --git a/trunk/net/ipv6/netfilter/Makefile b/trunk/net/ipv6/netfilter/Makefile index 4513eab77397..ac1dfebde175 100644 --- a/trunk/net/ipv6/netfilter/Makefile +++ b/trunk/net/ipv6/netfilter/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o -obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o # objects for l3 independent conntrack nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 7083e1cfb2f5..99502c5da4c4 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -530,7 +530,7 @@ check_match(struct ip6t_entry_match *m, unsigned int hookmask, unsigned int *i) { - struct xt_match *match; + struct ip6t_match *match; int ret; match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, @@ -564,14 +564,14 @@ check_match(struct ip6t_entry_match *m, return ret; } -static struct xt_target ip6t_standard_target; +static struct ip6t_target ip6t_standard_target; static inline int check_entry(struct ip6t_entry *e, const char *name, unsigned int size, unsigned int *i) { struct ip6t_entry_target *t; - struct xt_target *target; + struct ip6t_target *target; int ret; unsigned int j; @@ -1348,13 +1348,13 @@ icmp6_checkentry(const char *tablename, } /* The built-in targets: standard (NULL) and error. */ -static struct xt_target ip6t_standard_target = { +static struct ip6t_target ip6t_standard_target = { .name = IP6T_STANDARD_TARGET, .targetsize = sizeof(int), .family = AF_INET6, }; -static struct xt_target ip6t_error_target = { +static struct ip6t_target ip6t_error_target = { .name = IP6T_ERROR_TARGET, .target = ip6t_error, .targetsize = IP6T_FUNCTION_MAXNAMELEN, @@ -1371,7 +1371,7 @@ static struct nf_sockopt_ops ip6t_sockopts = { .get = do_ip6t_get_ctl, }; -static struct xt_match icmp6_matchstruct = { +static struct ip6t_match icmp6_matchstruct = { .name = "icmp6", .match = &icmp6_match, .matchsize = sizeof(struct ip6t_icmp), diff --git a/trunk/net/ipv6/netfilter/ip6t_HL.c b/trunk/net/ipv6/netfilter/ip6t_HL.c index 04e500172fb4..435750f664dd 100644 --- a/trunk/net/ipv6/netfilter/ip6t_HL.c +++ b/trunk/net/ipv6/netfilter/ip6t_HL.c @@ -9,13 +9,12 @@ #include #include #include -#include -#include +#include #include MODULE_AUTHOR("Maciej Soltysiak "); -MODULE_DESCRIPTION("IP6 tables Hop Limit modification module"); +MODULE_DESCRIPTION("IP tables Hop Limit modification module"); MODULE_LICENSE("GPL"); static unsigned int ip6t_hl_target(struct sk_buff **pskb, @@ -53,9 +52,10 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb, break; } - ip6h->hop_limit = new_hl; + if (new_hl != ip6h->hop_limit) + ip6h->hop_limit = new_hl; - return XT_CONTINUE; + return IP6T_CONTINUE; } static int ip6t_hl_checkentry(const char *tablename, @@ -79,9 +79,8 @@ static int ip6t_hl_checkentry(const char *tablename, return 1; } -static struct xt_target ip6t_HL = { +static struct ip6t_target ip6t_HL = { .name = "HL", - .family = AF_INET6, .target = ip6t_hl_target, .targetsize = sizeof(struct ip6t_HL_info), .table = "mangle", @@ -91,12 +90,12 @@ static struct xt_target ip6t_HL = { static int __init ip6t_hl_init(void) { - return xt_register_target(&ip6t_HL); + return ip6t_register_target(&ip6t_HL); } static void __exit ip6t_hl_fini(void) { - xt_unregister_target(&ip6t_HL); + ip6t_unregister_target(&ip6t_HL); } module_init(ip6t_hl_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_LOG.c b/trunk/net/ipv6/netfilter/ip6t_LOG.c index 5587a77b884c..33b1faa90d74 100644 --- a/trunk/net/ipv6/netfilter/ip6t_LOG.c +++ b/trunk/net/ipv6/netfilter/ip6t_LOG.c @@ -21,7 +21,6 @@ #include #include #include -#include #include MODULE_AUTHOR("Jan Rekorajski "); @@ -443,7 +442,7 @@ ip6t_log_target(struct sk_buff **pskb, ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix); - return XT_CONTINUE; + return IP6T_CONTINUE; } @@ -467,9 +466,8 @@ static int ip6t_log_checkentry(const char *tablename, return 1; } -static struct xt_target ip6t_log_reg = { +static struct ip6t_target ip6t_log_reg = { .name = "LOG", - .family = AF_INET6, .target = ip6t_log_target, .targetsize = sizeof(struct ip6t_log_info), .checkentry = ip6t_log_checkentry, @@ -484,11 +482,8 @@ static struct nf_logger ip6t_logger = { static int __init ip6t_log_init(void) { - int ret; - - ret = xt_register_target(&ip6t_log_reg); - if (ret < 0) - return ret; + if (ip6t_register_target(&ip6t_log_reg)) + return -EINVAL; if (nf_log_register(PF_INET6, &ip6t_logger) < 0) { printk(KERN_WARNING "ip6t_LOG: not logging via system console " "since somebody else already registered for PF_INET6\n"); @@ -502,7 +497,7 @@ static int __init ip6t_log_init(void) static void __exit ip6t_log_fini(void) { nf_log_unregister_logger(&ip6t_logger); - xt_unregister_target(&ip6t_log_reg); + ip6t_unregister_target(&ip6t_log_reg); } module_init(ip6t_log_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_REJECT.c b/trunk/net/ipv6/netfilter/ip6t_REJECT.c index 278349c18793..311eae82feb3 100644 --- a/trunk/net/ipv6/netfilter/ip6t_REJECT.c +++ b/trunk/net/ipv6/netfilter/ip6t_REJECT.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -235,7 +234,7 @@ static int check(const char *tablename, } else if (rejinfo->with == IP6T_TCP_RESET) { /* Must specify that it's a TCP packet */ if (e->ipv6.proto != IPPROTO_TCP - || (e->ipv6.invflags & XT_INV_PROTO)) { + || (e->ipv6.invflags & IP6T_INV_PROTO)) { DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); return 0; } @@ -243,9 +242,8 @@ static int check(const char *tablename, return 1; } -static struct xt_target ip6t_reject_reg = { +static struct ip6t_target ip6t_reject_reg = { .name = "REJECT", - .family = AF_INET6, .target = reject6_target, .targetsize = sizeof(struct ip6t_reject_info), .table = "filter", @@ -257,12 +255,12 @@ static struct xt_target ip6t_reject_reg = { static int __init ip6t_reject_init(void) { - return xt_register_target(&ip6t_reject_reg); + return ip6t_register_target(&ip6t_reject_reg); } static void __exit ip6t_reject_fini(void) { - xt_unregister_target(&ip6t_reject_reg); + ip6t_unregister_target(&ip6t_reject_reg); } module_init(ip6t_reject_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_ah.c b/trunk/net/ipv6/netfilter/ip6t_ah.c index 456c76adcbf6..46486645eb75 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ah.c +++ b/trunk/net/ipv6/netfilter/ip6t_ah.c @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -119,9 +118,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match ah_match = { +static struct ip6t_match ah_match = { .name = "ah", - .family = AF_INET6, .match = match, .matchsize = sizeof(struct ip6t_ah), .checkentry = checkentry, @@ -130,12 +128,12 @@ static struct xt_match ah_match = { static int __init ip6t_ah_init(void) { - return xt_register_match(&ah_match); + return ip6t_register_match(&ah_match); } static void __exit ip6t_ah_fini(void) { - xt_unregister_match(&ah_match); + ip6t_unregister_match(&ah_match); } module_init(ip6t_ah_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_eui64.c b/trunk/net/ipv6/netfilter/ip6t_eui64.c index 967bed71d4a8..4f6b84c8f4ab 100644 --- a/trunk/net/ipv6/netfilter/ip6t_eui64.c +++ b/trunk/net/ipv6/netfilter/ip6t_eui64.c @@ -12,7 +12,6 @@ #include #include -#include #include MODULE_DESCRIPTION("IPv6 EUI64 address checking match"); @@ -62,9 +61,8 @@ match(const struct sk_buff *skb, return 0; } -static struct xt_match eui64_match = { +static struct ip6t_match eui64_match = { .name = "eui64", - .family = AF_INET6, .match = match, .matchsize = sizeof(int), .hooks = (1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) | @@ -74,12 +72,12 @@ static struct xt_match eui64_match = { static int __init ip6t_eui64_init(void) { - return xt_register_match(&eui64_match); + return ip6t_register_match(&eui64_match); } static void __exit ip6t_eui64_fini(void) { - xt_unregister_match(&eui64_match); + ip6t_unregister_match(&eui64_match); } module_init(ip6t_eui64_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_frag.c b/trunk/net/ipv6/netfilter/ip6t_frag.c index 5a5da71321b6..cd22eaaccdca 100644 --- a/trunk/net/ipv6/netfilter/ip6t_frag.c +++ b/trunk/net/ipv6/netfilter/ip6t_frag.c @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -136,9 +135,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match frag_match = { +static struct ip6t_match frag_match = { .name = "frag", - .family = AF_INET6, .match = match, .matchsize = sizeof(struct ip6t_frag), .checkentry = checkentry, @@ -147,12 +145,12 @@ static struct xt_match frag_match = { static int __init ip6t_frag_init(void) { - return xt_register_match(&frag_match); + return ip6t_register_match(&frag_match); } static void __exit ip6t_frag_fini(void) { - xt_unregister_match(&frag_match); + ip6t_unregister_match(&frag_match); } module_init(ip6t_frag_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_hbh.c b/trunk/net/ipv6/netfilter/ip6t_hbh.c index d2373c7cd354..3f25babe0440 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hbh.c +++ b/trunk/net/ipv6/netfilter/ip6t_hbh.c @@ -16,7 +16,6 @@ #include -#include #include #include diff --git a/trunk/net/ipv6/netfilter/ip6t_hl.c b/trunk/net/ipv6/netfilter/ip6t_hl.c index 601cc1211c62..44a729e17c48 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hl.c +++ b/trunk/net/ipv6/netfilter/ip6t_hl.c @@ -8,12 +8,11 @@ * published by the Free Software Foundation. */ -#include #include #include #include -#include +#include MODULE_AUTHOR("Maciej Soltysiak "); MODULE_DESCRIPTION("IP tables Hop Limit matching module"); @@ -49,9 +48,8 @@ static int match(const struct sk_buff *skb, return 0; } -static struct xt_match hl_match = { +static struct ip6t_match hl_match = { .name = "hl", - .family = AF_INET6, .match = match, .matchsize = sizeof(struct ip6t_hl_info), .me = THIS_MODULE, @@ -59,12 +57,13 @@ static struct xt_match hl_match = { static int __init ip6t_hl_init(void) { - return xt_register_match(&hl_match); + return ip6t_register_match(&hl_match); } static void __exit ip6t_hl_fini(void) { - xt_unregister_match(&hl_match); + ip6t_unregister_match(&hl_match); + } module_init(ip6t_hl_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_ipv6header.c b/trunk/net/ipv6/netfilter/ip6t_ipv6header.c index 26ac084adefc..3093c398002f 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/trunk/net/ipv6/netfilter/ip6t_ipv6header.c @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -141,9 +140,8 @@ ipv6header_checkentry(const char *tablename, return 1; } -static struct xt_match ip6t_ipv6header_match = { +static struct ip6t_match ip6t_ipv6header_match = { .name = "ipv6header", - .family = AF_INET6, .match = &ipv6header_match, .matchsize = sizeof(struct ip6t_ipv6header_info), .checkentry = &ipv6header_checkentry, @@ -153,12 +151,12 @@ static struct xt_match ip6t_ipv6header_match = { static int __init ipv6header_init(void) { - return xt_register_match(&ip6t_ipv6header_match); + return ip6t_register_match(&ip6t_ipv6header_match); } static void __exit ipv6header_exit(void) { - xt_unregister_match(&ip6t_ipv6header_match); + ip6t_unregister_match(&ip6t_ipv6header_match); } module_init(ipv6header_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_mh.c b/trunk/net/ipv6/netfilter/ip6t_mh.c deleted file mode 100644 index 2c7efc6a506d..000000000000 --- a/trunk/net/ipv6/netfilter/ip6t_mh.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C)2006 USAGI/WIDE Project - * - * 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. - * - * Author: - * Masahide NAKAMURA @USAGI - * - * Based on net/netfilter/xt_tcpudp.c - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_DESCRIPTION("ip6t_tables match for MH"); -MODULE_LICENSE("GPL"); - -#ifdef DEBUG_IP_FIREWALL_USER -#define duprintf(format, args...) printk(format , ## args) -#else -#define duprintf(format, args...) -#endif - -/* Returns 1 if the type is matched by the range, 0 otherwise */ -static inline int -type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert) -{ - int ret; - - ret = (type >= min && type <= max) ^ invert; - return ret; -} - -static int -match(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const struct xt_match *match, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop) -{ - struct ip6_mh _mh, *mh; - const struct ip6t_mh *mhinfo = matchinfo; - - /* Must not be a fragment. */ - if (offset) - return 0; - - mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); - if (mh == NULL) { - /* We've been asked to examine this packet, and we - can't. Hence, no choice but to drop. */ - duprintf("Dropping evil MH tinygram.\n"); - *hotdrop = 1; - return 0; - } - - return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type, - !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); -} - -/* Called when user tries to insert an entry of this type. */ -static int -mh_checkentry(const char *tablename, - const void *entry, - const struct xt_match *match, - void *matchinfo, - unsigned int hook_mask) -{ - const struct ip6t_mh *mhinfo = matchinfo; - - /* Must specify no unknown invflags */ - return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); -} - -static struct xt_match mh_match = { - .name = "mh", - .family = AF_INET6, - .checkentry = mh_checkentry, - .match = match, - .matchsize = sizeof(struct ip6t_mh), - .proto = IPPROTO_MH, - .me = THIS_MODULE, -}; - -static int __init ip6t_mh_init(void) -{ - return xt_register_match(&mh_match); -} - -static void __exit ip6t_mh_fini(void) -{ - xt_unregister_match(&mh_match); -} - -module_init(ip6t_mh_init); -module_exit(ip6t_mh_fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_owner.c b/trunk/net/ipv6/netfilter/ip6t_owner.c index 43738bba00b5..4eb9bbc4ebc3 100644 --- a/trunk/net/ipv6/netfilter/ip6t_owner.c +++ b/trunk/net/ipv6/netfilter/ip6t_owner.c @@ -16,7 +16,6 @@ #include #include -#include MODULE_AUTHOR("Marc Boucher "); MODULE_DESCRIPTION("IP6 tables owner matching module"); @@ -70,9 +69,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match owner_match = { +static struct ip6t_match owner_match = { .name = "owner", - .family = AF_INET6, .match = match, .matchsize = sizeof(struct ip6t_owner_info), .hooks = (1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING), @@ -82,12 +80,12 @@ static struct xt_match owner_match = { static int __init ip6t_owner_init(void) { - return xt_register_match(&owner_match); + return ip6t_register_match(&owner_match); } static void __exit ip6t_owner_fini(void) { - xt_unregister_match(&owner_match); + ip6t_unregister_match(&owner_match); } module_init(ip6t_owner_init); diff --git a/trunk/net/ipv6/netfilter/ip6t_rt.c b/trunk/net/ipv6/netfilter/ip6t_rt.c index 81ab00d8c182..54d7d14134fd 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rt.c +++ b/trunk/net/ipv6/netfilter/ip6t_rt.c @@ -16,7 +16,6 @@ #include -#include #include #include @@ -222,9 +221,8 @@ checkentry(const char *tablename, return 1; } -static struct xt_match rt_match = { +static struct ip6t_match rt_match = { .name = "rt", - .family = AF_INET6, .match = match, .matchsize = sizeof(struct ip6t_rt), .checkentry = checkentry, @@ -233,12 +231,12 @@ static struct xt_match rt_match = { static int __init ip6t_rt_init(void) { - return xt_register_match(&rt_match); + return ip6t_register_match(&rt_match); } static void __exit ip6t_rt_fini(void) { - xt_unregister_match(&rt_match); + ip6t_unregister_match(&rt_match); } module_init(ip6t_rt_init); diff --git a/trunk/net/ipv6/netfilter/ip6table_filter.c b/trunk/net/ipv6/netfilter/ip6table_filter.c index 112a21d0c6da..2fc07c74decf 100644 --- a/trunk/net/ipv6/netfilter/ip6table_filter.c +++ b/trunk/net/ipv6/netfilter/ip6table_filter.c @@ -19,6 +19,25 @@ MODULE_DESCRIPTION("ip6tables filter table"); #define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT)) +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + static struct { struct ip6t_replace repl; @@ -73,7 +92,7 @@ static struct } }; -static struct xt_table packet_filter = { +static struct ip6t_table packet_filter = { .name = "filter", .valid_hooks = FILTER_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, diff --git a/trunk/net/ipv6/netfilter/ip6table_mangle.c b/trunk/net/ipv6/netfilter/ip6table_mangle.c index 5f5aa0e51478..6250e86a6ddc 100644 --- a/trunk/net/ipv6/netfilter/ip6table_mangle.c +++ b/trunk/net/ipv6/netfilter/ip6table_mangle.c @@ -29,6 +29,25 @@ MODULE_DESCRIPTION("ip6tables mangle table"); #define DEBUGP(x, args...) #endif +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + static struct { struct ip6t_replace repl; @@ -103,7 +122,7 @@ static struct } }; -static struct xt_table packet_mangler = { +static struct ip6t_table packet_mangler = { .name = "mangle", .valid_hooks = MANGLE_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, diff --git a/trunk/net/ipv6/netfilter/ip6table_raw.c b/trunk/net/ipv6/netfilter/ip6table_raw.c index 277bf34638b4..b4154da575c0 100644 --- a/trunk/net/ipv6/netfilter/ip6table_raw.c +++ b/trunk/net/ipv6/netfilter/ip6table_raw.c @@ -14,6 +14,25 @@ #define DEBUGP(x, args...) #endif +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + static struct { struct ip6t_replace repl; diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index c2d8059e754e..4ae1b19ada5d 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -815,7 +815,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) goto out; if (hlimit < 0) { @@ -1094,19 +1094,10 @@ static void rawv6_close(struct sock *sk, long timeout) static int rawv6_init_sk(struct sock *sk) { - struct raw6_sock *rp = raw6_sk(sk); - - switch (inet_sk(sk)->num) { - case IPPROTO_ICMPV6: + if (inet_sk(sk)->num == IPPROTO_ICMPV6) { + struct raw6_sock *rp = raw6_sk(sk); rp->checksum = 1; rp->offset = 2; - break; - case IPPROTO_MH: - rp->checksum = 1; - rp->offset = 4; - break; - default: - break; } return(0); } diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 19c906f6efa1..5f0043c30b70 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt) static int inline rt6_check_dev(struct rt6_info *rt, int oif) { struct net_device *dev = rt->rt6i_dev; - int ret = 0; - - if (!oif) - return 2; - if (dev->flags & IFF_LOOPBACK) { - if (!WARN_ON(rt->rt6i_idev == NULL) && - rt->rt6i_idev->dev->ifindex == oif) - ret = 1; - else - return 0; - } - if (dev->ifindex == oif) + if (!oif || dev->ifindex == oif) return 2; - - return ret; + if ((dev->flags & IFF_LOOPBACK) && + rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif) + return 1; + return 0; } static int inline rt6_check_neigh(struct rt6_info *rt) @@ -2049,7 +2040,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags); if (nlh == NULL) - return -EMSGSIZE; + return -ENOBUFS; rtm = nlmsg_data(nlh); rtm->rtm_family = AF_INET6; @@ -2120,8 +2111,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, return nlmsg_end(skb, nlh); nla_put_failure: - nlmsg_cancel(skb, nlh); - return -EMSGSIZE; + return nlmsg_cancel(skb, nlh); } int rt6_dump_route(struct rt6_info *rt, void *p_arg) @@ -2232,12 +2222,9 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) goto errout; err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); - if (err < 0) { - /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ - WARN_ON(err == -EMSGSIZE); - kfree_skb(skb); - goto errout; - } + /* failure implies BUG in rt6_nlmsg_size() */ + BUG_ON(err < 0); + err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); errout: if (err < 0) diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 47cfeadac6dd..77b7b0911438 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -686,8 +686,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) goto done; dev = t->dev; } - unregister_netdevice(dev); - err = 0; + err = unregister_netdevice(dev); break; default: diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index dcb7b00a737d..c25e930c2c69 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -265,7 +265,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) goto failure; if (saddr == NULL) { diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 15e5195549cb..f52a5c3cc0a3 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -736,7 +736,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) goto out; if (hlimit < 0) { diff --git a/trunk/net/ipv6/xfrm6_mode_tunnel.c b/trunk/net/ipv6/xfrm6_mode_tunnel.c index 0bc866c0d83c..5e7d8a7d6414 100644 --- a/trunk/net/ipv6/xfrm6_mode_tunnel.c +++ b/trunk/net/ipv6/xfrm6_mode_tunnel.c @@ -25,12 +25,6 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) IP6_ECN_set_ce(inner_iph); } -static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb) -{ - if (INET_ECN_is_ce(ipv6_get_dsfield(skb->nh.ipv6h))) - IP_ECN_set_ce(skb->h.ipiph); -} - /* Add encapsulation header. * * The top IP header will be constructed per RFC 2401. The following fields @@ -46,7 +40,6 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb) static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { struct dst_entry *dst = skb->dst; - struct xfrm_dst *xdst = (struct xfrm_dst*)dst; struct ipv6hdr *iph, *top_iph; int dsfield; @@ -59,24 +52,16 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) skb->h.ipv6h = top_iph + 1; top_iph->version = 6; - if (xdst->route->ops->family == AF_INET6) { - top_iph->priority = iph->priority; - top_iph->flow_lbl[0] = iph->flow_lbl[0]; - top_iph->flow_lbl[1] = iph->flow_lbl[1]; - top_iph->flow_lbl[2] = iph->flow_lbl[2]; - top_iph->nexthdr = IPPROTO_IPV6; - } else { - top_iph->priority = 0; - top_iph->flow_lbl[0] = 0; - top_iph->flow_lbl[1] = 0; - top_iph->flow_lbl[2] = 0; - top_iph->nexthdr = IPPROTO_IPIP; - } + top_iph->priority = iph->priority; + top_iph->flow_lbl[0] = iph->flow_lbl[0]; + top_iph->flow_lbl[1] = iph->flow_lbl[1]; + top_iph->flow_lbl[2] = iph->flow_lbl[2]; dsfield = ipv6_get_dsfield(top_iph); dsfield = INET_ECN_encapsulate(dsfield, dsfield); if (x->props.flags & XFRM_STATE_NOECN) dsfield &= ~INET_ECN_MASK; ipv6_change_dsfield(top_iph, 0, dsfield); + top_iph->nexthdr = IPPROTO_IPV6; top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); @@ -87,8 +72,7 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { int err = -EINVAL; - if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6 - && skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPIP) + if (skb->nh.raw[IP6CB(skb)->nhoff] != IPPROTO_IPV6) goto out; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto out; @@ -97,16 +81,10 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) goto out; - if (skb->nh.raw[IP6CB(skb)->nhoff] == IPPROTO_IPV6) { - if (x->props.flags & XFRM_STATE_DECAP_DSCP) - ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h); - if (!(x->props.flags & XFRM_STATE_NOECN)) - ipip6_ecn_decapsulate(skb); - } else { - if (!(x->props.flags & XFRM_STATE_NOECN)) - ip6ip_ecn_decapsulate(skb); - skb->protocol = htons(ETH_P_IP); - } + if (x->props.flags & XFRM_STATE_DECAP_DSCP) + ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h); + if (!(x->props.flags & XFRM_STATE_NOECN)) + ipip6_ecn_decapsulate(skb); skb->mac.raw = memmove(skb->data - skb->mac_len, skb->mac.raw, skb->mac_len); skb->nh.raw = skb->data; diff --git a/trunk/net/ipv6/xfrm6_policy.c b/trunk/net/ipv6/xfrm6_policy.c index 59480e92177d..8dffd4daae9c 100644 --- a/trunk/net/ipv6/xfrm6_policy.c +++ b/trunk/net/ipv6/xfrm6_policy.c @@ -131,11 +131,13 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int struct dst_entry *dst, *dst_prev; struct rt6_info *rt0 = (struct rt6_info*)(*dst_p); struct rt6_info *rt = rt0; + struct in6_addr *remote = &fl->fl6_dst; + struct in6_addr *local = &fl->fl6_src; struct flowi fl_tunnel = { .nl_u = { .ip6_u = { - .saddr = fl->fl6_src, - .daddr = fl->fl6_dst, + .saddr = *local, + .daddr = *remote } } }; @@ -151,6 +153,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int for (i = 0; i < nx; i++) { struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops); struct xfrm_dst *xdst; + int tunnel = 0; if (unlikely(dst1 == NULL)) { err = -ENOBUFS; @@ -174,27 +177,19 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int dst1->next = dst_prev; dst_prev = dst1; - + if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { + remote = __xfrm6_bundle_addr_remote(xfrm[i], remote); + local = __xfrm6_bundle_addr_local(xfrm[i], local); + tunnel = 1; + } __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); trailer_len += xfrm[i]->props.trailer_len; - if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) { - unsigned short encap_family = xfrm[i]->props.family; - switch(encap_family) { - case AF_INET: - fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4; - fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4; - break; - case AF_INET6: - ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr*)&xfrm[i]->id.daddr.a6); - ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr*)&xfrm[i]->props.saddr.a6); - break; - default: - BUG_ON(1); - } - + if (tunnel) { + ipv6_addr_copy(&fl_tunnel.fl6_dst, remote); + ipv6_addr_copy(&fl_tunnel.fl6_src, local); err = xfrm_dst_lookup((struct xfrm_dst **) &rt, - &fl_tunnel, encap_family); + &fl_tunnel, AF_INET6); if (err) goto error; } else @@ -213,7 +208,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int i = 0; for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; - struct xfrm_state_afinfo *afinfo; dst_prev->xfrm = xfrm[i++]; dst_prev->dev = rt->u.dst.dev; @@ -230,17 +224,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int /* Copy neighbour for reachability confirmation */ dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); dst_prev->input = rt->u.dst.input; - /* XXX: When IPv4 is implemented as module and can be unloaded, - * we should manage reference to xfrm4_output in afinfo->output. - * Miyazawa - */ - afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); - if (!afinfo) { - dst = *dst_p; - goto error; - }; - dst_prev->output = afinfo->output; - xfrm_state_put_afinfo(afinfo); + dst_prev->output = xfrm6_output; /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); diff --git a/trunk/net/ipv6/xfrm6_state.c b/trunk/net/ipv6/xfrm6_state.c index 60ad5f074e0a..9ddaa9d41539 100644 --- a/trunk/net/ipv6/xfrm6_state.c +++ b/trunk/net/ipv6/xfrm6_state.c @@ -171,7 +171,6 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { .init_tempsel = __xfrm6_init_tempsel, .tmpl_sort = __xfrm6_tmpl_sort, .state_sort = __xfrm6_state_sort, - .output = xfrm6_output, }; void __init xfrm6_state_init(void) diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index 89f283c51dff..76c661566dfd 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -2035,27 +2035,19 @@ static void __exit ipx_proto_finito(void) ipxitf_cleanup(); - if (pSNAP_datalink) { - unregister_snap_client(pSNAP_datalink); - pSNAP_datalink = NULL; - } + unregister_snap_client(pSNAP_datalink); + pSNAP_datalink = NULL; - if (p8022_datalink) { - unregister_8022_client(p8022_datalink); - p8022_datalink = NULL; - } + unregister_8022_client(p8022_datalink); + p8022_datalink = NULL; dev_remove_pack(&ipx_8023_packet_type); - if (p8023_datalink) { - destroy_8023_client(p8023_datalink); - p8023_datalink = NULL; - } + destroy_8023_client(p8023_datalink); + p8023_datalink = NULL; dev_remove_pack(&ipx_dix_packet_type); - if (pEII_datalink) { - destroy_EII_client(pEII_datalink); - pEII_datalink = NULL; - } + destroy_EII_client(pEII_datalink); + pEII_datalink = NULL; proto_unregister(&ipx_proto); sock_unregister(ipx_family_ops.family); diff --git a/trunk/net/irda/irias_object.c b/trunk/net/irda/irias_object.c index 2a571b43ebec..b1ee99a59c0c 100644 --- a/trunk/net/irda/irias_object.c +++ b/trunk/net/irda/irias_object.c @@ -91,12 +91,6 @@ struct ias_object *irias_new_object( char *name, int id) obj->magic = IAS_OBJECT_MAGIC; obj->name = strndup(name, IAS_MAX_CLASSNAME); - if (!obj->name) { - IRDA_WARNING("%s(), Unable to allocate name!\n", - __FUNCTION__); - kfree(obj); - return NULL; - } obj->id = id; /* Locking notes : the attrib spinlock has lower precendence @@ -107,7 +101,6 @@ struct ias_object *irias_new_object( char *name, int id) if (obj->attribs == NULL) { IRDA_WARNING("%s(), Unable to allocate attribs!\n", __FUNCTION__); - kfree(obj->name); kfree(obj); return NULL; } @@ -364,15 +357,6 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, /* Insert value */ attrib->value = irias_new_integer_value(value); - if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __FUNCTION__); - if (attrib->value) - irias_delete_value(attrib->value); - kfree(attrib->name); - kfree(attrib); - return; - } irias_add_attrib(obj, attrib, owner); } @@ -407,15 +391,6 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); attrib->value = irias_new_octseq_value( octets, len); - if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __FUNCTION__); - if (attrib->value) - irias_delete_value(attrib->value); - kfree(attrib->name); - kfree(attrib); - return; - } irias_add_attrib(obj, attrib, owner); } @@ -449,15 +424,6 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); attrib->value = irias_new_string_value(value); - if (!attrib->name || !attrib->value) { - IRDA_WARNING("%s: Unable to allocate attribute!\n", - __FUNCTION__); - if (attrib->value) - irias_delete_value(attrib->value); - kfree(attrib->name); - kfree(attrib); - return; - } irias_add_attrib(obj, attrib, owner); } @@ -507,12 +473,6 @@ struct ias_value *irias_new_string_value(char *string) value->type = IAS_STRING; value->charset = CS_ASCII; value->t.string = strndup(string, IAS_MAX_STRING); - if (!value->t.string) { - IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); - kfree(value); - return NULL; - } - value->len = strlen(value->t.string); return value; diff --git a/trunk/net/irda/irlan/irlan_common.c b/trunk/net/irda/irlan/irlan_common.c index 310776dd6109..2bb04ac09329 100644 --- a/trunk/net/irda/irlan/irlan_common.c +++ b/trunk/net/irda/irlan/irlan_common.c @@ -144,18 +144,12 @@ static int __init irlan_init(void) /* Register with IrLMP as a client */ ckey = irlmp_register_client(hints, &irlan_client_discovery_indication, NULL, NULL); - if (!ckey) - goto err_ckey; - + /* Register with IrLMP as a service */ - skey = irlmp_register_service(hints); - if (!skey) - goto err_skey; + skey = irlmp_register_service(hints); /* Start the master IrLAN instance (the only one for now) */ - new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY); - if (!new) - goto err_open; + new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY); /* The master will only open its (listen) control TSAP */ irlan_provider_open_ctrl_tsap(new); @@ -164,17 +158,6 @@ static int __init irlan_init(void) irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS); return 0; - -err_open: - irlmp_unregister_service(skey); -err_skey: - irlmp_unregister_client(ckey); -err_ckey: -#ifdef CONFIG_PROC_FS - remove_proc_entry("irlan", proc_irda); -#endif /* CONFIG_PROC_FS */ - - return -ENOMEM; } static void __exit irlan_cleanup(void) diff --git a/trunk/net/iucv/Kconfig b/trunk/net/iucv/Kconfig deleted file mode 100644 index f8fcc3d10327..000000000000 --- a/trunk/net/iucv/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config IUCV - tristate "IUCV support (VM only)" - depends on S390 - help - Select this option if you want to use inter-user communication under - VM or VIF sockets. If you run on z/VM, say "Y" to enable a fast - communication link between VM guests. - -config AFIUCV - tristate "AF_IUCV support (VM only)" - depends on IUCV - help - Select this option if you want to use inter-user communication under - VM or VIF sockets. If you run on z/VM, say "Y" to enable a fast - communication link between VM guests. diff --git a/trunk/net/iucv/Makefile b/trunk/net/iucv/Makefile deleted file mode 100644 index 7bfdc8532675..000000000000 --- a/trunk/net/iucv/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for IUCV -# - -obj-$(CONFIG_IUCV) += iucv.o -obj-$(CONFIG_AFIUCV) += af_iucv.o diff --git a/trunk/net/iucv/af_iucv.c b/trunk/net/iucv/af_iucv.c deleted file mode 100644 index acc94214bde6..000000000000 --- a/trunk/net/iucv/af_iucv.c +++ /dev/null @@ -1,1077 +0,0 @@ -/* - * linux/net/iucv/af_iucv.c - * - * IUCV protocol stack for Linux on zSeries - * - * Copyright 2006 IBM Corporation - * - * Author(s): Jennifer Hunt - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define CONFIG_IUCV_SOCK_DEBUG 1 - -#define IPRMDATA 0x80 -#define VERSION "1.0" - -static char iucv_userid[80]; - -static struct proto_ops iucv_sock_ops; - -static struct proto iucv_proto = { - .name = "AF_IUCV", - .owner = THIS_MODULE, - .obj_size = sizeof(struct iucv_sock), -}; - -/* Call Back functions */ -static void iucv_callback_rx(struct iucv_path *, struct iucv_message *); -static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *); -static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]); -static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); -static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); - -static struct iucv_sock_list iucv_sk_list = { - .lock = RW_LOCK_UNLOCKED, - .autobind_name = ATOMIC_INIT(0) -}; - -static struct iucv_handler af_iucv_handler = { - .path_pending = iucv_callback_connreq, - .path_complete = iucv_callback_connack, - .path_severed = iucv_callback_connrej, - .message_pending = iucv_callback_rx, - .message_complete = iucv_callback_txdone -}; - -static inline void high_nmcpy(unsigned char *dst, char *src) -{ - memcpy(dst, src, 8); -} - -static inline void low_nmcpy(unsigned char *dst, char *src) -{ - memcpy(&dst[8], src, 8); -} - -/* Timers */ -static void iucv_sock_timeout(unsigned long arg) -{ - struct sock *sk = (struct sock *)arg; - - bh_lock_sock(sk); - sk->sk_err = ETIMEDOUT; - sk->sk_state_change(sk); - bh_unlock_sock(sk); - - iucv_sock_kill(sk); - sock_put(sk); -} - -static void iucv_sock_clear_timer(struct sock *sk) -{ - sk_stop_timer(sk, &sk->sk_timer); -} - -static void iucv_sock_init_timer(struct sock *sk) -{ - init_timer(&sk->sk_timer); - sk->sk_timer.function = iucv_sock_timeout; - sk->sk_timer.data = (unsigned long)sk; -} - -static struct sock *__iucv_get_sock_by_name(char *nm) -{ - struct sock *sk; - struct hlist_node *node; - - sk_for_each(sk, node, &iucv_sk_list.head) - if (!memcmp(&iucv_sk(sk)->src_name, nm, 8)) - return sk; - - return NULL; -} - -static void iucv_sock_destruct(struct sock *sk) -{ - skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); -} - -/* Cleanup Listen */ -static void iucv_sock_cleanup_listen(struct sock *parent) -{ - struct sock *sk; - - /* Close non-accepted connections */ - while ((sk = iucv_accept_dequeue(parent, NULL))) { - iucv_sock_close(sk); - iucv_sock_kill(sk); - } - - parent->sk_state = IUCV_CLOSED; - sock_set_flag(parent, SOCK_ZAPPED); -} - -/* Kill socket */ -static void iucv_sock_kill(struct sock *sk) -{ - if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) - return; - - iucv_sock_unlink(&iucv_sk_list, sk); - sock_set_flag(sk, SOCK_DEAD); - sock_put(sk); -} - -/* Close an IUCV socket */ -static void iucv_sock_close(struct sock *sk) -{ - unsigned char user_data[16]; - struct iucv_sock *iucv = iucv_sk(sk); - int err; - - iucv_sock_clear_timer(sk); - lock_sock(sk); - - switch(sk->sk_state) { - case IUCV_LISTEN: - iucv_sock_cleanup_listen(sk); - break; - - case IUCV_CONNECTED: - case IUCV_DISCONN: - err = 0; - if (iucv->path) { - low_nmcpy(user_data, iucv->src_name); - high_nmcpy(user_data, iucv->dst_name); - ASCEBC(user_data, sizeof(user_data)); - err = iucv_path_sever(iucv->path, user_data); - iucv_path_free(iucv->path); - iucv->path = NULL; - } - - sk->sk_state = IUCV_CLOSED; - sk->sk_state_change(sk); - sk->sk_err = ECONNRESET; - sk->sk_state_change(sk); - - skb_queue_purge(&iucv->send_skb_q); - - sock_set_flag(sk, SOCK_ZAPPED); - break; - - default: - sock_set_flag(sk, SOCK_ZAPPED); - break; - }; - - release_sock(sk); - iucv_sock_kill(sk); -} - -static void iucv_sock_init(struct sock *sk, struct sock *parent) -{ - if (parent) - sk->sk_type = parent->sk_type; -} - -static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) -{ - struct sock *sk; - - sk = sk_alloc(PF_IUCV, prio, &iucv_proto, 1); - if (!sk) - return NULL; - - sock_init_data(sock, sk); - INIT_LIST_HEAD(&iucv_sk(sk)->accept_q); - skb_queue_head_init(&iucv_sk(sk)->send_skb_q); - iucv_sk(sk)->send_tag = 0; - - sk->sk_destruct = iucv_sock_destruct; - sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; - sk->sk_allocation = GFP_DMA; - - sock_reset_flag(sk, SOCK_ZAPPED); - - sk->sk_protocol = proto; - sk->sk_state = IUCV_OPEN; - - iucv_sock_init_timer(sk); - - iucv_sock_link(&iucv_sk_list, sk); - return sk; -} - -/* Create an IUCV socket */ -static int iucv_sock_create(struct socket *sock, int protocol) -{ - struct sock *sk; - - if (sock->type != SOCK_STREAM) - return -ESOCKTNOSUPPORT; - - sock->state = SS_UNCONNECTED; - sock->ops = &iucv_sock_ops; - - sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL); - if (!sk) - return -ENOMEM; - - iucv_sock_init(sk, NULL); - - return 0; -} - -void iucv_sock_link(struct iucv_sock_list *l, struct sock *sk) -{ - write_lock_bh(&l->lock); - sk_add_node(sk, &l->head); - write_unlock_bh(&l->lock); -} - -void iucv_sock_unlink(struct iucv_sock_list *l, struct sock *sk) -{ - write_lock_bh(&l->lock); - sk_del_node_init(sk); - write_unlock_bh(&l->lock); -} - -void iucv_accept_enqueue(struct sock *parent, struct sock *sk) -{ - sock_hold(sk); - list_add_tail(&iucv_sk(sk)->accept_q, &iucv_sk(parent)->accept_q); - iucv_sk(sk)->parent = parent; - parent->sk_ack_backlog++; -} - -void iucv_accept_unlink(struct sock *sk) -{ - list_del_init(&iucv_sk(sk)->accept_q); - iucv_sk(sk)->parent->sk_ack_backlog--; - iucv_sk(sk)->parent = NULL; - sock_put(sk); -} - -struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock) -{ - struct iucv_sock *isk, *n; - struct sock *sk; - - list_for_each_entry_safe(isk, n, &iucv_sk(parent)->accept_q, accept_q){ - sk = (struct sock *) isk; - lock_sock(sk); - - if (sk->sk_state == IUCV_CLOSED) { - release_sock(sk); - iucv_accept_unlink(sk); - continue; - } - - if (sk->sk_state == IUCV_CONNECTED || - sk->sk_state == IUCV_SEVERED || - !newsock) { - iucv_accept_unlink(sk); - if (newsock) - sock_graft(sk, newsock); - - if (sk->sk_state == IUCV_SEVERED) - sk->sk_state = IUCV_DISCONN; - - release_sock(sk); - return sk; - } - - release_sock(sk); - } - return NULL; -} - -int iucv_sock_wait_state(struct sock *sk, int state, int state2, - unsigned long timeo) -{ - DECLARE_WAITQUEUE(wait, current); - int err = 0; - - add_wait_queue(sk->sk_sleep, &wait); - while (sk->sk_state != state && sk->sk_state != state2) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!timeo) { - err = -EAGAIN; - break; - } - - if (signal_pending(current)) { - err = sock_intr_errno(timeo); - break; - } - - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); - - err = sock_error(sk); - if (err) - break; - } - set_current_state(TASK_RUNNING); - remove_wait_queue(sk->sk_sleep, &wait); - return err; -} - -/* Bind an unbound socket */ -static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr, - int addr_len) -{ - struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr; - struct sock *sk = sock->sk; - struct iucv_sock *iucv; - int err; - - /* Verify the input sockaddr */ - if (!addr || addr->sa_family != AF_IUCV) - return -EINVAL; - - lock_sock(sk); - if (sk->sk_state != IUCV_OPEN) { - err = -EBADFD; - goto done; - } - - write_lock_bh(&iucv_sk_list.lock); - - iucv = iucv_sk(sk); - if (__iucv_get_sock_by_name(sa->siucv_name)) { - err = -EADDRINUSE; - goto done_unlock; - } - if (iucv->path) { - err = 0; - goto done_unlock; - } - - /* Bind the socket */ - memcpy(iucv->src_name, sa->siucv_name, 8); - - /* Copy the user id */ - memcpy(iucv->src_user_id, iucv_userid, 8); - sk->sk_state = IUCV_BOUND; - err = 0; - -done_unlock: - /* Release the socket list lock */ - write_unlock_bh(&iucv_sk_list.lock); -done: - release_sock(sk); - return err; -} - -/* Automatically bind an unbound socket */ -static int iucv_sock_autobind(struct sock *sk) -{ - struct iucv_sock *iucv = iucv_sk(sk); - char query_buffer[80]; - char name[12]; - int err = 0; - - /* Set the userid and name */ - cpcmd("QUERY USERID", query_buffer, sizeof(query_buffer), &err); - if (unlikely(err)) - return -EPROTO; - - memcpy(iucv->src_user_id, query_buffer, 8); - - write_lock_bh(&iucv_sk_list.lock); - - sprintf(name, "%08x", atomic_inc_return(&iucv_sk_list.autobind_name)); - while (__iucv_get_sock_by_name(name)) { - sprintf(name, "%08x", - atomic_inc_return(&iucv_sk_list.autobind_name)); - } - - write_unlock_bh(&iucv_sk_list.lock); - - memcpy(&iucv->src_name, name, 8); - - return err; -} - -/* Connect an unconnected socket */ -static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, - int alen, int flags) -{ - struct sockaddr_iucv *sa = (struct sockaddr_iucv *) addr; - struct sock *sk = sock->sk; - struct iucv_sock *iucv; - unsigned char user_data[16]; - int err; - - if (addr->sa_family != AF_IUCV || alen < sizeof(struct sockaddr_iucv)) - return -EINVAL; - - if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND) - return -EBADFD; - - if (sk->sk_type != SOCK_STREAM) - return -EINVAL; - - iucv = iucv_sk(sk); - - if (sk->sk_state == IUCV_OPEN) { - err = iucv_sock_autobind(sk); - if (unlikely(err)) - return err; - } - - lock_sock(sk); - - /* Set the destination information */ - memcpy(iucv_sk(sk)->dst_user_id, sa->siucv_user_id, 8); - memcpy(iucv_sk(sk)->dst_name, sa->siucv_name, 8); - - high_nmcpy(user_data, sa->siucv_name); - low_nmcpy(user_data, iucv_sk(sk)->src_name); - ASCEBC(user_data, sizeof(user_data)); - - iucv = iucv_sk(sk); - /* Create path. */ - iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT, - IPRMDATA, GFP_KERNEL); - err = iucv_path_connect(iucv->path, &af_iucv_handler, - sa->siucv_user_id, NULL, user_data, sk); - if (err) { - iucv_path_free(iucv->path); - iucv->path = NULL; - err = -ECONNREFUSED; - goto done; - } - - if (sk->sk_state != IUCV_CONNECTED) { - err = iucv_sock_wait_state(sk, IUCV_CONNECTED, IUCV_DISCONN, - sock_sndtimeo(sk, flags & O_NONBLOCK)); - } - - if (sk->sk_state == IUCV_DISCONN) { - release_sock(sk); - return -ECONNREFUSED; - } -done: - release_sock(sk); - return err; -} - -/* Move a socket into listening state. */ -static int iucv_sock_listen(struct socket *sock, int backlog) -{ - struct sock *sk = sock->sk; - int err; - - lock_sock(sk); - - err = -EINVAL; - if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM) - goto done; - - sk->sk_max_ack_backlog = backlog; - sk->sk_ack_backlog = 0; - sk->sk_state = IUCV_LISTEN; - err = 0; - -done: - release_sock(sk); - return err; -} - -/* Accept a pending connection */ -static int iucv_sock_accept(struct socket *sock, struct socket *newsock, - int flags) -{ - DECLARE_WAITQUEUE(wait, current); - struct sock *sk = sock->sk, *nsk; - long timeo; - int err = 0; - - lock_sock(sk); - - if (sk->sk_state != IUCV_LISTEN) { - err = -EBADFD; - goto done; - } - - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - - /* Wait for an incoming connection */ - add_wait_queue_exclusive(sk->sk_sleep, &wait); - while (!(nsk = iucv_accept_dequeue(sk, newsock))){ - set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; - break; - } - - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); - - if (sk->sk_state != IUCV_LISTEN) { - err = -EBADFD; - break; - } - - if (signal_pending(current)) { - err = sock_intr_errno(timeo); - break; - } - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(sk->sk_sleep, &wait); - - if (err) - goto done; - - newsock->state = SS_CONNECTED; - -done: - release_sock(sk); - return err; -} - -static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr, - int *len, int peer) -{ - struct sockaddr_iucv *siucv = (struct sockaddr_iucv *) addr; - struct sock *sk = sock->sk; - - addr->sa_family = AF_IUCV; - *len = sizeof(struct sockaddr_iucv); - - if (peer) { - memcpy(siucv->siucv_user_id, iucv_sk(sk)->dst_user_id, 8); - memcpy(siucv->siucv_name, &iucv_sk(sk)->dst_name, 8); - } else { - memcpy(siucv->siucv_user_id, iucv_sk(sk)->src_user_id, 8); - memcpy(siucv->siucv_name, iucv_sk(sk)->src_name, 8); - } - memset(&siucv->siucv_port, 0, sizeof(siucv->siucv_port)); - memset(&siucv->siucv_addr, 0, sizeof(siucv->siucv_addr)); - memset(siucv->siucv_nodeid, 0, sizeof(siucv->siucv_nodeid)); - - return 0; -} - -static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) -{ - struct sock *sk = sock->sk; - struct iucv_sock *iucv = iucv_sk(sk); - struct sk_buff *skb; - struct iucv_message txmsg; - int err; - - err = sock_error(sk); - if (err) - return err; - - if (msg->msg_flags & MSG_OOB) - return -EOPNOTSUPP; - - lock_sock(sk); - - if (sk->sk_shutdown & SEND_SHUTDOWN) { - err = -EPIPE; - goto out; - } - - if (sk->sk_state == IUCV_CONNECTED){ - if(!(skb = sock_alloc_send_skb(sk, len, - msg->msg_flags & MSG_DONTWAIT, - &err))) - return err; - - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)){ - err = -EFAULT; - goto fail; - } - - txmsg.class = 0; - txmsg.tag = iucv->send_tag++; - memcpy(skb->cb, &txmsg.tag, 4); - skb_queue_tail(&iucv->send_skb_q, skb); - err = iucv_message_send(iucv->path, &txmsg, 0, 0, - (void *) skb->data, skb->len); - if (err) { - if (err == 3) - printk(KERN_ERR "AF_IUCV msg limit exceeded\n"); - skb_unlink(skb, &iucv->send_skb_q); - err = -EPIPE; - goto fail; - } - - } else { - err = -ENOTCONN; - goto out; - } - - release_sock(sk); - return len; - -fail: - kfree_skb(skb); -out: - release_sock(sk); - return err; -} - -static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) -{ - int noblock = flags & MSG_DONTWAIT; - struct sock *sk = sock->sk; - int target, copied = 0; - struct sk_buff *skb; - int err = 0; - - if (flags & (MSG_OOB)) - return -EOPNOTSUPP; - - target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); - - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) { - if (sk->sk_shutdown & RCV_SHUTDOWN) - return 0; - return err; - } - - copied = min_t(unsigned int, skb->len, len); - - if (memcpy_toiovec(msg->msg_iov, skb->data, copied)) { - skb_queue_head(&sk->sk_receive_queue, skb); - if (copied == 0) - return -EFAULT; - } - - len -= copied; - - /* Mark read part of skb as used */ - if (!(flags & MSG_PEEK)) { - skb_pull(skb, copied); - - if (skb->len) { - skb_queue_head(&sk->sk_receive_queue, skb); - goto done; - } - - kfree_skb(skb); - } else - skb_queue_head(&sk->sk_receive_queue, skb); - -done: - return err ? : copied; -} - -static inline unsigned int iucv_accept_poll(struct sock *parent) -{ - struct iucv_sock *isk, *n; - struct sock *sk; - - list_for_each_entry_safe(isk, n, &iucv_sk(parent)->accept_q, accept_q){ - sk = (struct sock *) isk; - - if (sk->sk_state == IUCV_CONNECTED) - return POLLIN | POLLRDNORM; - } - - return 0; -} - -unsigned int iucv_sock_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - struct sock *sk = sock->sk; - unsigned int mask = 0; - - poll_wait(file, sk->sk_sleep, wait); - - if (sk->sk_state == IUCV_LISTEN) - return iucv_accept_poll(sk); - - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) - mask |= POLLERR; - - if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; - - if (sk->sk_shutdown == SHUTDOWN_MASK) - mask |= POLLHUP; - - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) - mask |= POLLIN | POLLRDNORM; - - if (sk->sk_state == IUCV_CLOSED) - mask |= POLLHUP; - - if (sock_writeable(sk)) - mask |= POLLOUT | POLLWRNORM | POLLWRBAND; - else - set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); - - return mask; -} - -static int iucv_sock_shutdown(struct socket *sock, int how) -{ - struct sock *sk = sock->sk; - struct iucv_sock *iucv = iucv_sk(sk); - struct iucv_message txmsg; - int err = 0; - u8 prmmsg[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; - - how++; - - if ((how & ~SHUTDOWN_MASK) || !how) - return -EINVAL; - - lock_sock(sk); - switch(sk->sk_state) { - case IUCV_CLOSED: - err = -ENOTCONN; - goto fail; - - default: - sk->sk_shutdown |= how; - break; - } - - if (how == SEND_SHUTDOWN || how == SHUTDOWN_MASK) { - txmsg.class = 0; - txmsg.tag = 0; - err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0, - (void *) prmmsg, 8); - if (err) { - switch(err) { - case 1: - err = -ENOTCONN; - break; - case 2: - err = -ECONNRESET; - break; - default: - err = -ENOTCONN; - break; - } - } - } - - if (how == RCV_SHUTDOWN || how == SHUTDOWN_MASK) { - err = iucv_path_quiesce(iucv_sk(sk)->path, NULL); - if (err) - err = -ENOTCONN; - - skb_queue_purge(&sk->sk_receive_queue); - } - - /* Wake up anyone sleeping in poll */ - sk->sk_state_change(sk); - -fail: - release_sock(sk); - return err; -} - -static int iucv_sock_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - int err = 0; - - if (!sk) - return 0; - - iucv_sock_close(sk); - - /* Unregister with IUCV base support */ - if (iucv_sk(sk)->path) { - iucv_path_sever(iucv_sk(sk)->path, NULL); - iucv_path_free(iucv_sk(sk)->path); - iucv_sk(sk)->path = NULL; - } - - if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime){ - lock_sock(sk); - err = iucv_sock_wait_state(sk, IUCV_CLOSED, 0, - sk->sk_lingertime); - release_sock(sk); - } - - sock_orphan(sk); - iucv_sock_kill(sk); - return err; -} - -/* Callback wrappers - called from iucv base support */ -static int iucv_callback_connreq(struct iucv_path *path, - u8 ipvmid[8], u8 ipuser[16]) -{ - unsigned char user_data[16]; - unsigned char nuser_data[16]; - unsigned char src_name[8]; - struct hlist_node *node; - struct sock *sk, *nsk; - struct iucv_sock *iucv, *niucv; - int err; - - memcpy(src_name, ipuser, 8); - EBCASC(src_name, 8); - /* Find out if this path belongs to af_iucv. */ - read_lock(&iucv_sk_list.lock); - iucv = NULL; - sk_for_each(sk, node, &iucv_sk_list.head) - if (sk->sk_state == IUCV_LISTEN && - !memcmp(&iucv_sk(sk)->src_name, src_name, 8)) { - /* - * Found a listening socket with - * src_name == ipuser[0-7]. - */ - iucv = iucv_sk(sk); - break; - } - read_unlock(&iucv_sk_list.lock); - if (!iucv) - /* No socket found, not one of our paths. */ - return -EINVAL; - - bh_lock_sock(sk); - - /* Check if parent socket is listening */ - low_nmcpy(user_data, iucv->src_name); - high_nmcpy(user_data, iucv->dst_name); - ASCEBC(user_data, sizeof(user_data)); - if (sk->sk_state != IUCV_LISTEN) { - err = iucv_path_sever(path, user_data); - goto fail; - } - - /* Check for backlog size */ - if (sk_acceptq_is_full(sk)) { - err = iucv_path_sever(path, user_data); - goto fail; - } - - /* Create the new socket */ - nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC); - if (!nsk){ - err = iucv_path_sever(path, user_data); - goto fail; - } - - niucv = iucv_sk(nsk); - iucv_sock_init(nsk, sk); - - /* Set the new iucv_sock */ - memcpy(niucv->dst_name, ipuser + 8, 8); - EBCASC(niucv->dst_name, 8); - memcpy(niucv->dst_user_id, ipvmid, 8); - memcpy(niucv->src_name, iucv->src_name, 8); - memcpy(niucv->src_user_id, iucv->src_user_id, 8); - niucv->path = path; - - /* Call iucv_accept */ - high_nmcpy(nuser_data, ipuser + 8); - memcpy(nuser_data + 8, niucv->src_name, 8); - ASCEBC(nuser_data + 8, 8); - - path->msglim = IUCV_QUEUELEN_DEFAULT; - err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); - if (err){ - err = iucv_path_sever(path, user_data); - goto fail; - } - - iucv_accept_enqueue(sk, nsk); - - /* Wake up accept */ - nsk->sk_state = IUCV_CONNECTED; - sk->sk_data_ready(sk, 1); - err = 0; -fail: - bh_unlock_sock(sk); - return 0; -} - -static void iucv_callback_connack(struct iucv_path *path, u8 ipuser[16]) -{ - struct sock *sk = path->private; - - sk->sk_state = IUCV_CONNECTED; - sk->sk_state_change(sk); -} - -static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) -{ - struct sock *sk = path->private; - struct sk_buff *skb; - int rc; - - if (sk->sk_shutdown & RCV_SHUTDOWN) - return; - - skb = alloc_skb(msg->length, GFP_ATOMIC | GFP_DMA); - if (!skb) { - iucv_message_reject(path, msg); - return; - } - - if (msg->flags & IPRMDATA) { - skb->data = NULL; - skb->len = 0; - } else { - rc = iucv_message_receive(path, msg, 0, skb->data, - msg->length, NULL); - if (rc) { - kfree_skb(skb); - return; - } - - skb->h.raw = skb->data; - skb->nh.raw = skb->data; - skb->len = msg->length; - } - - if (sock_queue_rcv_skb(sk, skb)) - kfree_skb(skb); -} - -static void iucv_callback_txdone(struct iucv_path *path, - struct iucv_message *msg) -{ - struct sock *sk = path->private; - struct sk_buff *this; - struct sk_buff_head *list = &iucv_sk(sk)->send_skb_q; - struct sk_buff *list_skb = list->next; - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - - do { - this = list_skb; - list_skb = list_skb->next; - } while (memcmp(&msg->tag, this->cb, 4)); - - spin_unlock_irqrestore(&list->lock, flags); - - skb_unlink(this, &iucv_sk(sk)->send_skb_q); - kfree_skb(this); -} - -static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16]) -{ - struct sock *sk = path->private; - - if (!list_empty(&iucv_sk(sk)->accept_q)) - sk->sk_state = IUCV_SEVERED; - else - sk->sk_state = IUCV_DISCONN; - - sk->sk_state_change(sk); -} - -static struct proto_ops iucv_sock_ops = { - .family = PF_IUCV, - .owner = THIS_MODULE, - .release = iucv_sock_release, - .bind = iucv_sock_bind, - .connect = iucv_sock_connect, - .listen = iucv_sock_listen, - .accept = iucv_sock_accept, - .getname = iucv_sock_getname, - .sendmsg = iucv_sock_sendmsg, - .recvmsg = iucv_sock_recvmsg, - .poll = iucv_sock_poll, - .ioctl = sock_no_ioctl, - .mmap = sock_no_mmap, - .socketpair = sock_no_socketpair, - .shutdown = iucv_sock_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt -}; - -static struct net_proto_family iucv_sock_family_ops = { - .family = AF_IUCV, - .owner = THIS_MODULE, - .create = iucv_sock_create, -}; - -static int afiucv_init(void) -{ - int err; - - if (!MACHINE_IS_VM) { - printk(KERN_ERR "AF_IUCV connection needs VM as base\n"); - err = -EPROTONOSUPPORT; - goto out; - } - cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); - if (unlikely(err)) { - printk(KERN_ERR "AF_IUCV needs the VM userid\n"); - err = -EPROTONOSUPPORT; - goto out; - } - - err = iucv_register(&af_iucv_handler, 0); - if (err) - goto out; - err = proto_register(&iucv_proto, 0); - if (err) - goto out_iucv; - err = sock_register(&iucv_sock_family_ops); - if (err) - goto out_proto; - printk(KERN_INFO "AF_IUCV lowlevel driver initialized\n"); - return 0; - -out_proto: - proto_unregister(&iucv_proto); -out_iucv: - iucv_unregister(&af_iucv_handler, 0); -out: - return err; -} - -static void __exit afiucv_exit(void) -{ - sock_unregister(PF_IUCV); - proto_unregister(&iucv_proto); - iucv_unregister(&af_iucv_handler, 0); - - printk(KERN_INFO "AF_IUCV lowlevel driver unloaded\n"); -} - -module_init(afiucv_init); -module_exit(afiucv_exit); - -MODULE_AUTHOR("Jennifer Hunt "); -MODULE_DESCRIPTION("IUCV Sockets ver " VERSION); -MODULE_VERSION(VERSION); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_IUCV); diff --git a/trunk/net/iucv/iucv.c b/trunk/net/iucv/iucv.c deleted file mode 100644 index 1b10d576f222..000000000000 --- a/trunk/net/iucv/iucv.c +++ /dev/null @@ -1,1619 +0,0 @@ -/* - * IUCV base infrastructure. - * - * Copyright 2001, 2006 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): - * Original source: - * Alan Altmark (Alan_Altmark@us.ibm.com) Sept. 2000 - * Xenia Tkatschow (xenia@us.ibm.com) - * 2Gb awareness and general cleanup: - * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) - * Rewritten for af_iucv: - * Martin Schwidefsky - * - * Documentation used: - * The original source - * CP Programming Service, IBM document # SC24-5760 - * - * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * FLAGS: - * All flags are defined in the field IPFLAGS1 of each function - * and can be found in CP Programming Services. - * IPSRCCLS - Indicates you have specified a source class. - * IPTRGCLS - Indicates you have specified a target class. - * IPFGPID - Indicates you have specified a pathid. - * IPFGMID - Indicates you have specified a message ID. - * IPNORPY - Indicates a one-way message. No reply expected. - * IPALL - Indicates that all paths are affected. - */ -#define IUCV_IPSRCCLS 0x01 -#define IUCV_IPTRGCLS 0x01 -#define IUCV_IPFGPID 0x02 -#define IUCV_IPFGMID 0x04 -#define IUCV_IPNORPY 0x10 -#define IUCV_IPALL 0x80 - -static int iucv_bus_match (struct device *dev, struct device_driver *drv) -{ - return 0; -} - -struct bus_type iucv_bus = { - .name = "iucv", - .match = iucv_bus_match, -}; - -struct device *iucv_root; -static int iucv_available; - -/* General IUCV interrupt structure */ -struct iucv_irq_data { - u16 ippathid; - u8 ipflags1; - u8 iptype; - u32 res2[8]; -}; - -struct iucv_work { - struct list_head list; - struct iucv_irq_data data; -}; - -static LIST_HEAD(iucv_work_queue); -static DEFINE_SPINLOCK(iucv_work_lock); - -static struct iucv_irq_data *iucv_irq_data; -static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE; -static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE; - -static void iucv_tasklet_handler(unsigned long); -static DECLARE_TASKLET(iucv_tasklet, iucv_tasklet_handler,0); - -enum iucv_command_codes { - IUCV_QUERY = 0, - IUCV_RETRIEVE_BUFFER = 2, - IUCV_SEND = 4, - IUCV_RECEIVE = 5, - IUCV_REPLY = 6, - IUCV_REJECT = 8, - IUCV_PURGE = 9, - IUCV_ACCEPT = 10, - IUCV_CONNECT = 11, - IUCV_DECLARE_BUFFER = 12, - IUCV_QUIESCE = 13, - IUCV_RESUME = 14, - IUCV_SEVER = 15, - IUCV_SETMASK = 16, -}; - -/* - * Error messages that are used with the iucv_sever function. They get - * converted to EBCDIC. - */ -static char iucv_error_no_listener[16] = "NO LISTENER"; -static char iucv_error_no_memory[16] = "NO MEMORY"; -static char iucv_error_pathid[16] = "INVALID PATHID"; - -/* - * iucv_handler_list: List of registered handlers. - */ -static LIST_HEAD(iucv_handler_list); - -/* - * iucv_path_table: an array of iucv_path structures. - */ -static struct iucv_path **iucv_path_table; -static unsigned long iucv_max_pathid; - -/* - * iucv_lock: spinlock protecting iucv_handler_list and iucv_pathid_table - */ -static DEFINE_SPINLOCK(iucv_table_lock); - -/* - * iucv_tasklet_cpu: contains the number of the cpu executing the tasklet. - * Needed for iucv_path_sever called from tasklet. - */ -static int iucv_tasklet_cpu = -1; - -/* - * Mutex and wait queue for iucv_register/iucv_unregister. - */ -static DEFINE_MUTEX(iucv_register_mutex); - -/* - * Counter for number of non-smp capable handlers. - */ -static int iucv_nonsmp_handler; - -/* - * IUCV control data structure. Used by iucv_path_accept, iucv_path_connect, - * iucv_path_quiesce and iucv_path_sever. - */ -struct iucv_cmd_control { - u16 ippathid; - u8 ipflags1; - u8 iprcode; - u16 ipmsglim; - u16 res1; - u8 ipvmid[8]; - u8 ipuser[16]; - u8 iptarget[8]; -} __attribute__ ((packed,aligned(8))); - -/* - * Data in parameter list iucv structure. Used by iucv_message_send, - * iucv_message_send2way and iucv_message_reply. - */ -struct iucv_cmd_dpl { - u16 ippathid; - u8 ipflags1; - u8 iprcode; - u32 ipmsgid; - u32 iptrgcls; - u8 iprmmsg[8]; - u32 ipsrccls; - u32 ipmsgtag; - u32 ipbfadr2; - u32 ipbfln2f; - u32 res; -} __attribute__ ((packed,aligned(8))); - -/* - * Data in buffer iucv structure. Used by iucv_message_receive, - * iucv_message_reject, iucv_message_send, iucv_message_send2way - * and iucv_declare_cpu. - */ -struct iucv_cmd_db { - u16 ippathid; - u8 ipflags1; - u8 iprcode; - u32 ipmsgid; - u32 iptrgcls; - u32 ipbfadr1; - u32 ipbfln1f; - u32 ipsrccls; - u32 ipmsgtag; - u32 ipbfadr2; - u32 ipbfln2f; - u32 res; -} __attribute__ ((packed,aligned(8))); - -/* - * Purge message iucv structure. Used by iucv_message_purge. - */ -struct iucv_cmd_purge { - u16 ippathid; - u8 ipflags1; - u8 iprcode; - u32 ipmsgid; - u8 ipaudit[3]; - u8 res1[5]; - u32 res2; - u32 ipsrccls; - u32 ipmsgtag; - u32 res3[3]; -} __attribute__ ((packed,aligned(8))); - -/* - * Set mask iucv structure. Used by iucv_enable_cpu. - */ -struct iucv_cmd_set_mask { - u8 ipmask; - u8 res1[2]; - u8 iprcode; - u32 res2[9]; -} __attribute__ ((packed,aligned(8))); - -union iucv_param { - struct iucv_cmd_control ctrl; - struct iucv_cmd_dpl dpl; - struct iucv_cmd_db db; - struct iucv_cmd_purge purge; - struct iucv_cmd_set_mask set_mask; -}; - -/* - * Anchor for per-cpu IUCV command parameter block. - */ -static union iucv_param *iucv_param; - -/** - * iucv_call_b2f0 - * @code: identifier of IUCV call to CP. - * @parm: pointer to a struct iucv_parm block - * - * Calls CP to execute IUCV commands. - * - * Returns the result of the CP IUCV call. - */ -static inline int iucv_call_b2f0(int command, union iucv_param *parm) -{ - register unsigned long reg0 asm ("0"); - register unsigned long reg1 asm ("1"); - int ccode; - - reg0 = command; - reg1 = virt_to_phys(parm); - asm volatile( - " .long 0xb2f01000\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode), "=m" (*parm), "+d" (reg0), "+a" (reg1) - : "m" (*parm) : "cc"); - return (ccode == 1) ? parm->ctrl.iprcode : ccode; -} - -/** - * iucv_query_maxconn - * - * Determines the maximum number of connections that may be established. - * - * Returns the maximum number of connections or -EPERM is IUCV is not - * available. - */ -static int iucv_query_maxconn(void) -{ - register unsigned long reg0 asm ("0"); - register unsigned long reg1 asm ("1"); - void *param; - int ccode; - - param = kzalloc(sizeof(union iucv_param), GFP_KERNEL|GFP_DMA); - if (!param) - return -ENOMEM; - reg0 = IUCV_QUERY; - reg1 = (unsigned long) param; - asm volatile ( - " .long 0xb2f01000\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc"); - if (ccode == 0) - iucv_max_pathid = reg0; - kfree(param); - return ccode ? -EPERM : 0; -} - -/** - * iucv_allow_cpu - * @data: unused - * - * Allow iucv interrupts on this cpu. - */ -static void iucv_allow_cpu(void *data) -{ - int cpu = smp_processor_id(); - union iucv_param *parm; - - /* - * Enable all iucv interrupts. - * ipmask contains bits for the different interrupts - * 0x80 - Flag to allow nonpriority message pending interrupts - * 0x40 - Flag to allow priority message pending interrupts - * 0x20 - Flag to allow nonpriority message completion interrupts - * 0x10 - Flag to allow priority message completion interrupts - * 0x08 - Flag to allow IUCV control interrupts - */ - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->set_mask.ipmask = 0xf8; - iucv_call_b2f0(IUCV_SETMASK, parm); - - /* Set indication that iucv interrupts are allowed for this cpu. */ - cpu_set(cpu, iucv_irq_cpumask); -} - -/** - * iucv_block_cpu - * @data: unused - * - * Block iucv interrupts on this cpu. - */ -static void iucv_block_cpu(void *data) -{ - int cpu = smp_processor_id(); - union iucv_param *parm; - - /* Disable all iucv interrupts. */ - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - iucv_call_b2f0(IUCV_SETMASK, parm); - - /* Clear indication that iucv interrupts are allowed for this cpu. */ - cpu_clear(cpu, iucv_irq_cpumask); -} - -/** - * iucv_declare_cpu - * @data: unused - * - * Declare a interupt buffer on this cpu. - */ -static void iucv_declare_cpu(void *data) -{ - int cpu = smp_processor_id(); - union iucv_param *parm; - int rc; - - if (cpu_isset(cpu, iucv_buffer_cpumask)) - return; - - /* Declare interrupt buffer. */ - parm = percpu_ptr(iucv_param, cpu); - memset(parm, 0, sizeof(union iucv_param)); - parm->db.ipbfadr1 = virt_to_phys(percpu_ptr(iucv_irq_data, cpu)); - rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); - if (rc) { - char *err = "Unknown"; - switch(rc) { - case 0x03: - err = "Directory error"; - break; - case 0x0a: - err = "Invalid length"; - break; - case 0x13: - err = "Buffer already exists"; - break; - case 0x3e: - err = "Buffer overlap"; - break; - case 0x5c: - err = "Paging or storage error"; - break; - } - printk(KERN_WARNING "iucv_register: iucv_declare_buffer " - "on cpu %i returned error 0x%02x (%s)\n", cpu, rc, err); - return; - } - - /* Set indication that an iucv buffer exists for this cpu. */ - cpu_set(cpu, iucv_buffer_cpumask); - - if (iucv_nonsmp_handler == 0 || cpus_empty(iucv_irq_cpumask)) - /* Enable iucv interrupts on this cpu. */ - iucv_allow_cpu(NULL); - else - /* Disable iucv interrupts on this cpu. */ - iucv_block_cpu(NULL); -} - -/** - * iucv_retrieve_cpu - * @data: unused - * - * Retrieve interrupt buffer on this cpu. - */ -static void iucv_retrieve_cpu(void *data) -{ - int cpu = smp_processor_id(); - union iucv_param *parm; - - if (!cpu_isset(cpu, iucv_buffer_cpumask)) - return; - - /* Block iucv interrupts. */ - iucv_block_cpu(NULL); - - /* Retrieve interrupt buffer. */ - parm = percpu_ptr(iucv_param, cpu); - iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); - - /* Clear indication that an iucv buffer exists for this cpu. */ - cpu_clear(cpu, iucv_buffer_cpumask); -} - -/** - * iucv_setmask_smp - * - * Allow iucv interrupts on all cpus. - */ -static void iucv_setmask_mp(void) -{ - int cpu; - - for_each_online_cpu(cpu) - /* Enable all cpus with a declared buffer. */ - if (cpu_isset(cpu, iucv_buffer_cpumask) && - !cpu_isset(cpu, iucv_irq_cpumask)) - smp_call_function_on(iucv_allow_cpu, NULL, 0, 1, cpu); -} - -/** - * iucv_setmask_up - * - * Allow iucv interrupts on a single cpus. - */ -static void iucv_setmask_up(void) -{ - cpumask_t cpumask; - int cpu; - - /* Disable all cpu but the first in cpu_irq_cpumask. */ - cpumask = iucv_irq_cpumask; - cpu_clear(first_cpu(iucv_irq_cpumask), cpumask); - for_each_cpu_mask(cpu, cpumask) - smp_call_function_on(iucv_block_cpu, NULL, 0, 1, cpu); -} - -/** - * iucv_enable - * - * This function makes iucv ready for use. It allocates the pathid - * table, declares an iucv interrupt buffer and enables the iucv - * interrupts. Called when the first user has registered an iucv - * handler. - */ -static int iucv_enable(void) -{ - size_t alloc_size; - int cpu, rc; - - rc = -ENOMEM; - alloc_size = iucv_max_pathid * sizeof(struct iucv_path); - iucv_path_table = kzalloc(alloc_size, GFP_KERNEL); - if (!iucv_path_table) - goto out; - /* Declare per cpu buffers. */ - rc = -EIO; - for_each_online_cpu(cpu) - smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); - if (cpus_empty(iucv_buffer_cpumask)) - /* No cpu could declare an iucv buffer. */ - goto out_path; - return 0; - -out_path: - kfree(iucv_path_table); -out: - return rc; -} - -/** - * iucv_disable - * - * This function shuts down iucv. It disables iucv interrupts, retrieves - * the iucv interrupt buffer and frees the pathid table. Called after the - * last user unregister its iucv handler. - */ -static void iucv_disable(void) -{ - on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1); - kfree(iucv_path_table); -} - -#ifdef CONFIG_HOTPLUG_CPU -static int __cpuinit iucv_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -{ - cpumask_t cpumask; - long cpu = (long) hcpu; - - switch (action) { - case CPU_UP_PREPARE: - if (!percpu_populate(iucv_irq_data, - sizeof(struct iucv_irq_data), - GFP_KERNEL|GFP_DMA, cpu)) - return NOTIFY_BAD; - if (!percpu_populate(iucv_param, sizeof(union iucv_param), - GFP_KERNEL|GFP_DMA, cpu)) { - percpu_depopulate(iucv_irq_data, cpu); - return NOTIFY_BAD; - } - break; - case CPU_UP_CANCELED: - case CPU_DEAD: - percpu_depopulate(iucv_param, cpu); - percpu_depopulate(iucv_irq_data, cpu); - break; - case CPU_ONLINE: - case CPU_DOWN_FAILED: - smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); - break; - case CPU_DOWN_PREPARE: - cpumask = iucv_buffer_cpumask; - cpu_clear(cpu, cpumask); - if (cpus_empty(cpumask)) - /* Can't offline last IUCV enabled cpu. */ - return NOTIFY_BAD; - smp_call_function_on(iucv_retrieve_cpu, NULL, 0, 1, cpu); - if (cpus_empty(iucv_irq_cpumask)) - smp_call_function_on(iucv_allow_cpu, NULL, 0, 1, - first_cpu(iucv_buffer_cpumask)); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block iucv_cpu_notifier = { - .notifier_call = iucv_cpu_notify, -}; -#endif - -/** - * iucv_sever_pathid - * @pathid: path identification number. - * @userdata: 16-bytes of user data. - * - * Sever an iucv path to free up the pathid. Used internally. - */ -static int iucv_sever_pathid(u16 pathid, u8 userdata[16]) -{ - union iucv_param *parm; - - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (userdata) - memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); - parm->ctrl.ippathid = pathid; - return iucv_call_b2f0(IUCV_SEVER, parm); -} - -/** - * __iucv_cleanup_pathid - * @dummy: unused dummy argument - * - * Nop function called via smp_call_function to force work items from - * pending external iucv interrupts to the work queue. - */ -static void __iucv_cleanup_pathid(void *dummy) -{ -} - -/** - * iucv_cleanup_pathid - * @pathid: 16 bit pathid - * - * Function called after a path has been severed to find all remaining - * work items for the now stale pathid. The caller needs to hold the - * iucv_table_lock. - */ -static void iucv_cleanup_pathid(u16 pathid) -{ - struct iucv_work *p, *n; - - /* - * Path is severed, the pathid can be reused immediatly on - * a iucv connect or a connection pending interrupt. - * iucv_path_connect and connection pending interrupt will - * wait until the iucv_table_lock is released before the - * recycled pathid enters the system. - * Force remaining interrupts to the work queue, then - * scan the work queue for items of this path. - */ - smp_call_function(__iucv_cleanup_pathid, NULL, 0, 1); - spin_lock_irq(&iucv_work_lock); - list_for_each_entry_safe(p, n, &iucv_work_queue, list) { - /* Remove work items for pathid except connection pending */ - if (p->data.ippathid == pathid && p->data.iptype != 0x01) { - list_del(&p->list); - kfree(p); - } - } - spin_unlock_irq(&iucv_work_lock); -} - -/** - * iucv_register: - * @handler: address of iucv handler structure - * @smp: != 0 indicates that the handler can deal with out of order messages - * - * Registers a driver with IUCV. - * - * Returns 0 on success, -ENOMEM if the memory allocation for the pathid - * table failed, or -EIO if IUCV_DECLARE_BUFFER failed on all cpus. - */ -int iucv_register(struct iucv_handler *handler, int smp) -{ - int rc; - - if (!iucv_available) - return -ENOSYS; - mutex_lock(&iucv_register_mutex); - if (!smp) - iucv_nonsmp_handler++; - if (list_empty(&iucv_handler_list)) { - rc = iucv_enable(); - if (rc) - goto out_mutex; - } else if (!smp && iucv_nonsmp_handler == 1) - iucv_setmask_up(); - INIT_LIST_HEAD(&handler->paths); - - spin_lock_irq(&iucv_table_lock); - list_add_tail(&handler->list, &iucv_handler_list); - spin_unlock_irq(&iucv_table_lock); - rc = 0; -out_mutex: - mutex_unlock(&iucv_register_mutex); - return rc; -} - -/** - * iucv_unregister - * @handler: address of iucv handler structure - * @smp: != 0 indicates that the handler can deal with out of order messages - * - * Unregister driver from IUCV. - */ -void iucv_unregister(struct iucv_handler *handler, int smp) -{ - struct iucv_path *p, *n; - - mutex_lock(&iucv_register_mutex); - spin_lock_bh(&iucv_table_lock); - /* Remove handler from the iucv_handler_list. */ - list_del_init(&handler->list); - /* Sever all pathids still refering to the handler. */ - list_for_each_entry_safe(p, n, &handler->paths, list) { - iucv_sever_pathid(p->pathid, NULL); - iucv_path_table[p->pathid] = NULL; - list_del(&p->list); - iucv_cleanup_pathid(p->pathid); - iucv_path_free(p); - } - spin_unlock_bh(&iucv_table_lock); - if (!smp) - iucv_nonsmp_handler--; - if (list_empty(&iucv_handler_list)) - iucv_disable(); - else if (!smp && iucv_nonsmp_handler == 0) - iucv_setmask_mp(); - mutex_unlock(&iucv_register_mutex); -} - -/** - * iucv_path_accept - * @path: address of iucv path structure - * @handler: address of iucv handler structure - * @userdata: 16 bytes of data reflected to the communication partner - * @private: private data passed to interrupt handlers for this path - * - * This function is issued after the user received a connection pending - * external interrupt and now wishes to complete the IUCV communication path. - * - * Returns the result of the CP IUCV call. - */ -int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, - u8 userdata[16], void *private) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - /* Prepare parameter block. */ - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->ctrl.ippathid = path->pathid; - parm->ctrl.ipmsglim = path->msglim; - if (userdata) - memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); - parm->ctrl.ipflags1 = path->flags; - - rc = iucv_call_b2f0(IUCV_ACCEPT, parm); - if (!rc) { - path->private = private; - path->msglim = parm->ctrl.ipmsglim; - path->flags = parm->ctrl.ipflags1; - } - local_bh_enable(); - return rc; -} - -/** - * iucv_path_connect - * @path: address of iucv path structure - * @handler: address of iucv handler structure - * @userid: 8-byte user identification - * @system: 8-byte target system identification - * @userdata: 16 bytes of data reflected to the communication partner - * @private: private data passed to interrupt handlers for this path - * - * This function establishes an IUCV path. Although the connect may complete - * successfully, you are not able to use the path until you receive an IUCV - * Connection Complete external interrupt. - * - * Returns the result of the CP IUCV call. - */ -int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, - u8 userid[8], u8 system[8], u8 userdata[16], - void *private) -{ - union iucv_param *parm; - int rc; - - preempt_disable(); - if (iucv_tasklet_cpu != smp_processor_id()) - spin_lock_bh(&iucv_table_lock); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->ctrl.ipmsglim = path->msglim; - parm->ctrl.ipflags1 = path->flags; - if (userid) { - memcpy(parm->ctrl.ipvmid, userid, sizeof(parm->ctrl.ipvmid)); - ASCEBC(parm->ctrl.ipvmid, sizeof(parm->ctrl.ipvmid)); - EBC_TOUPPER(parm->ctrl.ipvmid, sizeof(parm->ctrl.ipvmid)); - } - if (system) { - memcpy(parm->ctrl.iptarget, system, - sizeof(parm->ctrl.iptarget)); - ASCEBC(parm->ctrl.iptarget, sizeof(parm->ctrl.iptarget)); - EBC_TOUPPER(parm->ctrl.iptarget, sizeof(parm->ctrl.iptarget)); - } - if (userdata) - memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); - - rc = iucv_call_b2f0(IUCV_CONNECT, parm); - if (!rc) { - if (parm->ctrl.ippathid < iucv_max_pathid) { - path->pathid = parm->ctrl.ippathid; - path->msglim = parm->ctrl.ipmsglim; - path->flags = parm->ctrl.ipflags1; - path->handler = handler; - path->private = private; - list_add_tail(&path->list, &handler->paths); - iucv_path_table[path->pathid] = path; - } else { - iucv_sever_pathid(parm->ctrl.ippathid, - iucv_error_pathid); - rc = -EIO; - } - } - if (iucv_tasklet_cpu != smp_processor_id()) - spin_unlock_bh(&iucv_table_lock); - preempt_enable(); - return rc; -} - -/** - * iucv_path_quiesce: - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function temporarily suspends incoming messages on an IUCV path. - * You can later reactivate the path by invoking the iucv_resume function. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (userdata) - memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); - parm->ctrl.ippathid = path->pathid; - rc = iucv_call_b2f0(IUCV_QUIESCE, parm); - local_bh_enable(); - return rc; -} - -/** - * iucv_path_resume: - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function resumes incoming messages on an IUCV path that has - * been stopped with iucv_path_quiesce. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_resume(struct iucv_path *path, u8 userdata[16]) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (userdata) - memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); - parm->ctrl.ippathid = path->pathid; - rc = iucv_call_b2f0(IUCV_RESUME, parm); - local_bh_enable(); - return rc; -} - -/** - * iucv_path_sever - * @path: address of iucv path structure - * @userdata: 16 bytes of data reflected to the communication partner - * - * This function terminates an IUCV path. - * - * Returns the result from the CP IUCV call. - */ -int iucv_path_sever(struct iucv_path *path, u8 userdata[16]) -{ - int rc; - - - preempt_disable(); - if (iucv_tasklet_cpu != smp_processor_id()) - spin_lock_bh(&iucv_table_lock); - rc = iucv_sever_pathid(path->pathid, userdata); - if (!rc) { - iucv_path_table[path->pathid] = NULL; - list_del_init(&path->list); - iucv_cleanup_pathid(path->pathid); - } - if (iucv_tasklet_cpu != smp_processor_id()) - spin_unlock_bh(&iucv_table_lock); - preempt_enable(); - return rc; -} - -/** - * iucv_message_purge - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @srccls: source class of message - * - * Cancels a message you have sent. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg, - u32 srccls) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->purge.ippathid = path->pathid; - parm->purge.ipmsgid = msg->id; - parm->purge.ipsrccls = srccls; - parm->purge.ipflags1 = IUCV_IPSRCCLS | IUCV_IPFGMID | IUCV_IPFGPID; - rc = iucv_call_b2f0(IUCV_PURGE, parm); - if (!rc) { - msg->audit = (*(u32 *) &parm->purge.ipaudit) >> 8; - msg->tag = parm->purge.ipmsgtag; - } - local_bh_enable(); - return rc; -} - -/** - * iucv_message_receive - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the message is received (IUCV_IPBUFLST) - * @buffer: address of data buffer or address of struct iucv_array - * @size: length of data buffer - * @residual: - * - * This function receives messages that are being sent to you over - * established paths. This function will deal with RMDATA messages - * embedded in struct iucv_message as well. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg, - u8 flags, void *buffer, size_t size, size_t *residual) -{ - union iucv_param *parm; - struct iucv_array *array; - u8 *rmmsg; - size_t copy; - int rc; - - if (msg->flags & IUCV_IPRMDATA) { - /* - * Message is 8 bytes long and has been stored to the - * message descriptor itself. - */ - rc = (size < 8) ? 5 : 0; - if (residual) - *residual = abs(size - 8); - rmmsg = msg->rmmsg; - if (flags & IUCV_IPBUFLST) { - /* Copy to struct iucv_array. */ - size = (size < 8) ? size : 8; - for (array = buffer; size > 0; array++) { - copy = min_t(size_t, size, array->length); - memcpy((u8 *)(addr_t) array->address, - rmmsg, copy); - rmmsg += copy; - size -= copy; - } - } else { - /* Copy to direct buffer. */ - memcpy(buffer, rmmsg, min_t(size_t, size, 8)); - } - return 0; - } - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->db.ipbfadr1 = (u32)(addr_t) buffer; - parm->db.ipbfln1f = (u32) size; - parm->db.ipmsgid = msg->id; - parm->db.ippathid = path->pathid; - parm->db.iptrgcls = msg->class; - parm->db.ipflags1 = (flags | IUCV_IPFGPID | - IUCV_IPFGMID | IUCV_IPTRGCLS); - rc = iucv_call_b2f0(IUCV_RECEIVE, parm); - if (!rc || rc == 5) { - msg->flags = parm->db.ipflags1; - if (residual) - *residual = parm->db.ipbfln1f; - } - local_bh_enable(); - return rc; -} - -/** - * iucv_message_reject - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * - * The reject function refuses a specified message. Between the time you - * are notified of a message and the time that you complete the message, - * the message may be rejected. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - parm->db.ippathid = path->pathid; - parm->db.ipmsgid = msg->id; - parm->db.iptrgcls = msg->class; - parm->db.ipflags1 = (IUCV_IPTRGCLS | IUCV_IPFGMID | IUCV_IPFGPID); - rc = iucv_call_b2f0(IUCV_REJECT, parm); - local_bh_enable(); - return rc; -} - -/** - * iucv_message_reply - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the reply is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST) - * @reply: address of reply data buffer or address of struct iucv_array - * @size: length of reply data buffer - * - * This function responds to the two-way messages that you receive. You - * must identify completely the message to which you wish to reply. ie, - * pathid, msgid, and trgcls. Prmmsg signifies the data is moved into - * the parameter list. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg, - u8 flags, void *reply, size_t size) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (flags & IUCV_IPRMDATA) { - parm->dpl.ippathid = path->pathid; - parm->dpl.ipflags1 = flags; - parm->dpl.ipmsgid = msg->id; - parm->dpl.iptrgcls = msg->class; - memcpy(parm->dpl.iprmmsg, reply, min_t(size_t, size, 8)); - } else { - parm->db.ipbfadr1 = (u32)(addr_t) reply; - parm->db.ipbfln1f = (u32) size; - parm->db.ippathid = path->pathid; - parm->db.ipflags1 = flags; - parm->db.ipmsgid = msg->id; - parm->db.iptrgcls = msg->class; - } - rc = iucv_call_b2f0(IUCV_REPLY, parm); - local_bh_enable(); - return rc; -} - -/** - * iucv_message_send - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST) - * @srccls: source class of message - * @buffer: address of send buffer or address of struct iucv_array - * @size: length of send buffer - * - * This function transmits data to another application. Data to be - * transmitted is in a buffer and this is a one-way message and the - * receiver will not reply to the message. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_send(struct iucv_path *path, struct iucv_message *msg, - u8 flags, u32 srccls, void *buffer, size_t size) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (flags & IUCV_IPRMDATA) { - /* Message of 8 bytes can be placed into the parameter list. */ - parm->dpl.ippathid = path->pathid; - parm->dpl.ipflags1 = flags | IUCV_IPNORPY; - parm->dpl.iptrgcls = msg->class; - parm->dpl.ipsrccls = srccls; - parm->dpl.ipmsgtag = msg->tag; - memcpy(parm->dpl.iprmmsg, buffer, 8); - } else { - parm->db.ipbfadr1 = (u32)(addr_t) buffer; - parm->db.ipbfln1f = (u32) size; - parm->db.ippathid = path->pathid; - parm->db.ipflags1 = flags | IUCV_IPNORPY; - parm->db.iptrgcls = msg->class; - parm->db.ipsrccls = srccls; - parm->db.ipmsgtag = msg->tag; - } - rc = iucv_call_b2f0(IUCV_SEND, parm); - if (!rc) - msg->id = parm->db.ipmsgid; - local_bh_enable(); - return rc; -} - -/** - * iucv_message_send2way - * @path: address of iucv path structure - * @msg: address of iucv msg structure - * @flags: how the message is sent and the reply is received - * (IUCV_IPRMDATA, IUCV_IPBUFLST, IUCV_IPPRTY, IUCV_ANSLST) - * @srccls: source class of message - * @buffer: address of send buffer or address of struct iucv_array - * @size: length of send buffer - * @ansbuf: address of answer buffer or address of struct iucv_array - * @asize: size of reply buffer - * - * This function transmits data to another application. Data to be - * transmitted is in a buffer. The receiver of the send is expected to - * reply to the message and a buffer is provided into which IUCV moves - * the reply to this message. - * - * Returns the result from the CP IUCV call. - */ -int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg, - u8 flags, u32 srccls, void *buffer, size_t size, - void *answer, size_t asize, size_t *residual) -{ - union iucv_param *parm; - int rc; - - local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); - memset(parm, 0, sizeof(union iucv_param)); - if (flags & IUCV_IPRMDATA) { - parm->dpl.ippathid = path->pathid; - parm->dpl.ipflags1 = path->flags; /* priority message */ - parm->dpl.iptrgcls = msg->class; - parm->dpl.ipsrccls = srccls; - parm->dpl.ipmsgtag = msg->tag; - parm->dpl.ipbfadr2 = (u32)(addr_t) answer; - parm->dpl.ipbfln2f = (u32) asize; - memcpy(parm->dpl.iprmmsg, buffer, 8); - } else { - parm->db.ippathid = path->pathid; - parm->db.ipflags1 = path->flags; /* priority message */ - parm->db.iptrgcls = msg->class; - parm->db.ipsrccls = srccls; - parm->db.ipmsgtag = msg->tag; - parm->db.ipbfadr1 = (u32)(addr_t) buffer; - parm->db.ipbfln1f = (u32) size; - parm->db.ipbfadr2 = (u32)(addr_t) answer; - parm->db.ipbfln2f = (u32) asize; - } - rc = iucv_call_b2f0(IUCV_SEND, parm); - if (!rc) - msg->id = parm->db.ipmsgid; - local_bh_enable(); - return rc; -} - -/** - * iucv_path_pending - * @data: Pointer to external interrupt buffer - * - * Process connection pending work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_path_pending { - u16 ippathid; - u8 ipflags1; - u8 iptype; - u16 ipmsglim; - u16 res1; - u8 ipvmid[8]; - u8 ipuser[16]; - u32 res3; - u8 ippollfg; - u8 res4[3]; -} __attribute__ ((packed)); - -static void iucv_path_pending(struct iucv_irq_data *data) -{ - struct iucv_path_pending *ipp = (void *) data; - struct iucv_handler *handler; - struct iucv_path *path; - char *error; - - BUG_ON(iucv_path_table[ipp->ippathid]); - /* New pathid, handler found. Create a new path struct. */ - error = iucv_error_no_memory; - path = iucv_path_alloc(ipp->ipmsglim, ipp->ipflags1, GFP_ATOMIC); - if (!path) - goto out_sever; - path->pathid = ipp->ippathid; - iucv_path_table[path->pathid] = path; - EBCASC(ipp->ipvmid, 8); - - /* Call registered handler until one is found that wants the path. */ - list_for_each_entry(handler, &iucv_handler_list, list) { - if (!handler->path_pending) - continue; - /* - * Add path to handler to allow a call to iucv_path_sever - * inside the path_pending function. If the handler returns - * an error remove the path from the handler again. - */ - list_add(&path->list, &handler->paths); - path->handler = handler; - if (!handler->path_pending(path, ipp->ipvmid, ipp->ipuser)) - return; - list_del(&path->list); - path->handler = NULL; - } - /* No handler wanted the path. */ - iucv_path_table[path->pathid] = NULL; - iucv_path_free(path); - error = iucv_error_no_listener; -out_sever: - iucv_sever_pathid(ipp->ippathid, error); -} - -/** - * iucv_path_complete - * @data: Pointer to external interrupt buffer - * - * Process connection complete work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_path_complete { - u16 ippathid; - u8 ipflags1; - u8 iptype; - u16 ipmsglim; - u16 res1; - u8 res2[8]; - u8 ipuser[16]; - u32 res3; - u8 ippollfg; - u8 res4[3]; -} __attribute__ ((packed)); - -static void iucv_path_complete(struct iucv_irq_data *data) -{ - struct iucv_path_complete *ipc = (void *) data; - struct iucv_path *path = iucv_path_table[ipc->ippathid]; - - BUG_ON(!path || !path->handler); - if (path->handler->path_complete) - path->handler->path_complete(path, ipc->ipuser); -} - -/** - * iucv_path_severed - * @data: Pointer to external interrupt buffer - * - * Process connection severed work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_path_severed { - u16 ippathid; - u8 res1; - u8 iptype; - u32 res2; - u8 res3[8]; - u8 ipuser[16]; - u32 res4; - u8 ippollfg; - u8 res5[3]; -} __attribute__ ((packed)); - -static void iucv_path_severed(struct iucv_irq_data *data) -{ - struct iucv_path_severed *ips = (void *) data; - struct iucv_path *path = iucv_path_table[ips->ippathid]; - - BUG_ON(!path || !path->handler); - if (path->handler->path_severed) - path->handler->path_severed(path, ips->ipuser); - else { - iucv_sever_pathid(path->pathid, NULL); - iucv_path_table[path->pathid] = NULL; - list_del_init(&path->list); - iucv_cleanup_pathid(path->pathid); - iucv_path_free(path); - } -} - -/** - * iucv_path_quiesced - * @data: Pointer to external interrupt buffer - * - * Process connection quiesced work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_path_quiesced { - u16 ippathid; - u8 res1; - u8 iptype; - u32 res2; - u8 res3[8]; - u8 ipuser[16]; - u32 res4; - u8 ippollfg; - u8 res5[3]; -} __attribute__ ((packed)); - -static void iucv_path_quiesced(struct iucv_irq_data *data) -{ - struct iucv_path_quiesced *ipq = (void *) data; - struct iucv_path *path = iucv_path_table[ipq->ippathid]; - - BUG_ON(!path || !path->handler); - if (path->handler->path_quiesced) - path->handler->path_quiesced(path, ipq->ipuser); -} - -/** - * iucv_path_resumed - * @data: Pointer to external interrupt buffer - * - * Process connection resumed work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_path_resumed { - u16 ippathid; - u8 res1; - u8 iptype; - u32 res2; - u8 res3[8]; - u8 ipuser[16]; - u32 res4; - u8 ippollfg; - u8 res5[3]; -} __attribute__ ((packed)); - -static void iucv_path_resumed(struct iucv_irq_data *data) -{ - struct iucv_path_resumed *ipr = (void *) data; - struct iucv_path *path = iucv_path_table[ipr->ippathid]; - - BUG_ON(!path || !path->handler); - if (path->handler->path_resumed) - path->handler->path_resumed(path, ipr->ipuser); -} - -/** - * iucv_message_complete - * @data: Pointer to external interrupt buffer - * - * Process message complete work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_message_complete { - u16 ippathid; - u8 ipflags1; - u8 iptype; - u32 ipmsgid; - u32 ipaudit; - u8 iprmmsg[8]; - u32 ipsrccls; - u32 ipmsgtag; - u32 res; - u32 ipbfln2f; - u8 ippollfg; - u8 res2[3]; -} __attribute__ ((packed)); - -static void iucv_message_complete(struct iucv_irq_data *data) -{ - struct iucv_message_complete *imc = (void *) data; - struct iucv_path *path = iucv_path_table[imc->ippathid]; - struct iucv_message msg; - - BUG_ON(!path || !path->handler); - if (path->handler->message_complete) { - msg.flags = imc->ipflags1; - msg.id = imc->ipmsgid; - msg.audit = imc->ipaudit; - memcpy(msg.rmmsg, imc->iprmmsg, 8); - msg.class = imc->ipsrccls; - msg.tag = imc->ipmsgtag; - msg.length = imc->ipbfln2f; - path->handler->message_complete(path, &msg); - } -} - -/** - * iucv_message_pending - * @data: Pointer to external interrupt buffer - * - * Process message pending work item. Called from tasklet while holding - * iucv_table_lock. - */ -struct iucv_message_pending { - u16 ippathid; - u8 ipflags1; - u8 iptype; - u32 ipmsgid; - u32 iptrgcls; - union { - u32 iprmmsg1_u32; - u8 iprmmsg1[4]; - } ln1msg1; - union { - u32 ipbfln1f; - u8 iprmmsg2[4]; - } ln1msg2; - u32 res1[3]; - u32 ipbfln2f; - u8 ippollfg; - u8 res2[3]; -} __attribute__ ((packed)); - -static void iucv_message_pending(struct iucv_irq_data *data) -{ - struct iucv_message_pending *imp = (void *) data; - struct iucv_path *path = iucv_path_table[imp->ippathid]; - struct iucv_message msg; - - BUG_ON(!path || !path->handler); - if (path->handler->message_pending) { - msg.flags = imp->ipflags1; - msg.id = imp->ipmsgid; - msg.class = imp->iptrgcls; - if (imp->ipflags1 & IUCV_IPRMDATA) { - memcpy(msg.rmmsg, imp->ln1msg1.iprmmsg1, 8); - msg.length = 8; - } else - msg.length = imp->ln1msg2.ipbfln1f; - msg.reply_size = imp->ipbfln2f; - path->handler->message_pending(path, &msg); - } -} - -/** - * iucv_tasklet_handler: - * - * This tasklet loops over the queue of irq buffers created by - * iucv_external_interrupt, calls the appropriate action handler - * and then frees the buffer. - */ -static void iucv_tasklet_handler(unsigned long ignored) -{ - typedef void iucv_irq_fn(struct iucv_irq_data *); - static iucv_irq_fn *irq_fn[] = { - [0x01] = iucv_path_pending, - [0x02] = iucv_path_complete, - [0x03] = iucv_path_severed, - [0x04] = iucv_path_quiesced, - [0x05] = iucv_path_resumed, - [0x06] = iucv_message_complete, - [0x07] = iucv_message_complete, - [0x08] = iucv_message_pending, - [0x09] = iucv_message_pending, - }; - struct iucv_work *p; - - /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */ - spin_lock(&iucv_table_lock); - iucv_tasklet_cpu = smp_processor_id(); - - spin_lock_irq(&iucv_work_lock); - while (!list_empty(&iucv_work_queue)) { - p = list_entry(iucv_work_queue.next, struct iucv_work, list); - list_del_init(&p->list); - spin_unlock_irq(&iucv_work_lock); - irq_fn[p->data.iptype](&p->data); - kfree(p); - spin_lock_irq(&iucv_work_lock); - } - spin_unlock_irq(&iucv_work_lock); - - iucv_tasklet_cpu = -1; - spin_unlock(&iucv_table_lock); -} - -/** - * iucv_external_interrupt - * @code: irq code - * - * Handles external interrupts coming in from CP. - * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler(). - */ -static void iucv_external_interrupt(u16 code) -{ - struct iucv_irq_data *p; - struct iucv_work *work; - - p = percpu_ptr(iucv_irq_data, smp_processor_id()); - if (p->ippathid >= iucv_max_pathid) { - printk(KERN_WARNING "iucv_do_int: Got interrupt with " - "pathid %d > max_connections (%ld)\n", - p->ippathid, iucv_max_pathid - 1); - iucv_sever_pathid(p->ippathid, iucv_error_no_listener); - return; - } - if (p->iptype < 0x01 || p->iptype > 0x09) { - printk(KERN_ERR "iucv_do_int: unknown iucv interrupt\n"); - return; - } - work = kmalloc(sizeof(struct iucv_work), GFP_ATOMIC); - if (!work) { - printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); - return; - } - memcpy(&work->data, p, sizeof(work->data)); - spin_lock(&iucv_work_lock); - list_add_tail(&work->list, &iucv_work_queue); - spin_unlock(&iucv_work_lock); - tasklet_schedule(&iucv_tasklet); -} - -/** - * iucv_init - * - * Allocates and initializes various data structures. - */ -static int iucv_init(void) -{ - int rc; - - if (!MACHINE_IS_VM) { - rc = -EPROTONOSUPPORT; - goto out; - } - rc = iucv_query_maxconn(); - if (rc) - goto out; - rc = register_external_interrupt (0x4000, iucv_external_interrupt); - if (rc) - goto out; - rc = bus_register(&iucv_bus); - if (rc) - goto out_int; - iucv_root = s390_root_dev_register("iucv"); - if (IS_ERR(iucv_root)) { - rc = PTR_ERR(iucv_root); - goto out_bus; - } - /* Note: GFP_DMA used used to get memory below 2G */ - iucv_irq_data = percpu_alloc(sizeof(struct iucv_irq_data), - GFP_KERNEL|GFP_DMA); - if (!iucv_irq_data) { - rc = -ENOMEM; - goto out_root; - } - /* Allocate parameter blocks. */ - iucv_param = percpu_alloc(sizeof(union iucv_param), - GFP_KERNEL|GFP_DMA); - if (!iucv_param) { - rc = -ENOMEM; - goto out_extint; - } - register_hotcpu_notifier(&iucv_cpu_notifier); - ASCEBC(iucv_error_no_listener, 16); - ASCEBC(iucv_error_no_memory, 16); - ASCEBC(iucv_error_pathid, 16); - iucv_available = 1; - return 0; - -out_extint: - percpu_free(iucv_irq_data); -out_root: - s390_root_dev_unregister(iucv_root); -out_bus: - bus_unregister(&iucv_bus); -out_int: - unregister_external_interrupt(0x4000, iucv_external_interrupt); -out: - return rc; -} - -/** - * iucv_exit - * - * Frees everything allocated from iucv_init. - */ -static void iucv_exit(void) -{ - struct iucv_work *p, *n; - - spin_lock_irq(&iucv_work_lock); - list_for_each_entry_safe(p, n, &iucv_work_queue, list) - kfree(p); - spin_unlock_irq(&iucv_work_lock); - unregister_hotcpu_notifier(&iucv_cpu_notifier); - percpu_free(iucv_param); - percpu_free(iucv_irq_data); - s390_root_dev_unregister(iucv_root); - bus_unregister(&iucv_bus); - unregister_external_interrupt(0x4000, iucv_external_interrupt); -} - -subsys_initcall(iucv_init); -module_exit(iucv_exit); - -/** - * Export all public stuff - */ -EXPORT_SYMBOL (iucv_bus); -EXPORT_SYMBOL (iucv_root); -EXPORT_SYMBOL (iucv_register); -EXPORT_SYMBOL (iucv_unregister); -EXPORT_SYMBOL (iucv_path_accept); -EXPORT_SYMBOL (iucv_path_connect); -EXPORT_SYMBOL (iucv_path_quiesce); -EXPORT_SYMBOL (iucv_path_sever); -EXPORT_SYMBOL (iucv_message_purge); -EXPORT_SYMBOL (iucv_message_receive); -EXPORT_SYMBOL (iucv_message_reject); -EXPORT_SYMBOL (iucv_message_reply); -EXPORT_SYMBOL (iucv_message_send); -EXPORT_SYMBOL (iucv_message_send2way); - -MODULE_AUTHOR("(C) 2001 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); -MODULE_DESCRIPTION("Linux for S/390 IUCV lowlevel driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index b4e444063d1f..5dd5094659a1 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -2345,196 +2345,6 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb return err; } -#ifdef CONFIG_NET_KEY_MIGRATE -static int pfkey_sockaddr_pair_size(sa_family_t family) -{ - switch (family) { - case AF_INET: - return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2); -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2); -#endif - default: - return 0; - } - /* NOTREACHED */ -} - -static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, - xfrm_address_t *saddr, xfrm_address_t *daddr, - u16 *family) -{ - struct sockaddr *sa = (struct sockaddr *)(rq + 1); - if (rq->sadb_x_ipsecrequest_len < - pfkey_sockaddr_pair_size(sa->sa_family)) - return -EINVAL; - - switch (sa->sa_family) { - case AF_INET: - { - struct sockaddr_in *sin; - sin = (struct sockaddr_in *)sa; - if ((sin+1)->sin_family != AF_INET) - return -EINVAL; - memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4)); - sin++; - memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4)); - *family = AF_INET; - break; - } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - { - struct sockaddr_in6 *sin6; - sin6 = (struct sockaddr_in6 *)sa; - if ((sin6+1)->sin6_family != AF_INET6) - return -EINVAL; - memcpy(&saddr->a6, &sin6->sin6_addr, - sizeof(saddr->a6)); - sin6++; - memcpy(&daddr->a6, &sin6->sin6_addr, - sizeof(daddr->a6)); - *family = AF_INET6; - break; - } -#endif - default: - return -EINVAL; - } - - return 0; -} - -static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len, - struct xfrm_migrate *m) -{ - int err; - struct sadb_x_ipsecrequest *rq2; - - if (len <= sizeof(struct sadb_x_ipsecrequest) || - len < rq1->sadb_x_ipsecrequest_len) - return -EINVAL; - - /* old endoints */ - err = parse_sockaddr_pair(rq1, &m->old_saddr, &m->old_daddr, - &m->old_family); - if (err) - return err; - - rq2 = (struct sadb_x_ipsecrequest *)((u8 *)rq1 + rq1->sadb_x_ipsecrequest_len); - len -= rq1->sadb_x_ipsecrequest_len; - - if (len <= sizeof(struct sadb_x_ipsecrequest) || - len < rq2->sadb_x_ipsecrequest_len) - return -EINVAL; - - /* new endpoints */ - err = parse_sockaddr_pair(rq2, &m->new_saddr, &m->new_daddr, - &m->new_family); - if (err) - return err; - - if (rq1->sadb_x_ipsecrequest_proto != rq2->sadb_x_ipsecrequest_proto || - rq1->sadb_x_ipsecrequest_mode != rq2->sadb_x_ipsecrequest_mode || - rq1->sadb_x_ipsecrequest_reqid != rq2->sadb_x_ipsecrequest_reqid) - return -EINVAL; - - m->proto = rq1->sadb_x_ipsecrequest_proto; - m->mode = rq1->sadb_x_ipsecrequest_mode - 1; - m->reqid = rq1->sadb_x_ipsecrequest_reqid; - - return ((int)(rq1->sadb_x_ipsecrequest_len + - rq2->sadb_x_ipsecrequest_len)); -} - -static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, - struct sadb_msg *hdr, void **ext_hdrs) -{ - int i, len, ret, err = -EINVAL; - u8 dir; - struct sadb_address *sa; - struct sadb_x_policy *pol; - struct sadb_x_ipsecrequest *rq; - struct xfrm_selector sel; - struct xfrm_migrate m[XFRM_MAX_DEPTH]; - - if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1], - ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) || - !ext_hdrs[SADB_X_EXT_POLICY - 1]) { - err = -EINVAL; - goto out; - } - - pol = ext_hdrs[SADB_X_EXT_POLICY - 1]; - if (!pol) { - err = -EINVAL; - goto out; - } - - if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) { - err = -EINVAL; - goto out; - } - - dir = pol->sadb_x_policy_dir - 1; - memset(&sel, 0, sizeof(sel)); - - /* set source address info of selector */ - sa = ext_hdrs[SADB_EXT_ADDRESS_SRC - 1]; - sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr); - sel.prefixlen_s = sa->sadb_address_prefixlen; - sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - sel.sport = ((struct sockaddr_in *)(sa + 1))->sin_port; - if (sel.sport) - sel.sport_mask = ~0; - - /* set destination address info of selector */ - sa = ext_hdrs[SADB_EXT_ADDRESS_DST - 1], - pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr); - sel.prefixlen_d = sa->sadb_address_prefixlen; - sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto); - sel.dport = ((struct sockaddr_in *)(sa + 1))->sin_port; - if (sel.dport) - sel.dport_mask = ~0; - - rq = (struct sadb_x_ipsecrequest *)(pol + 1); - - /* extract ipsecrequests */ - i = 0; - len = pol->sadb_x_policy_len * 8 - sizeof(struct sadb_x_policy); - - while (len > 0 && i < XFRM_MAX_DEPTH) { - ret = ipsecrequests_to_migrate(rq, len, &m[i]); - if (ret < 0) { - err = ret; - goto out; - } else { - rq = (struct sadb_x_ipsecrequest *)((u8 *)rq + ret); - len -= ret; - i++; - } - } - - if (!i || len > 0) { - err = -EINVAL; - goto out; - } - - return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i); - - out: - return err; -} -#else -static int pfkey_migrate(struct sock *sk, struct sk_buff *skb, - struct sadb_msg *hdr, void **ext_hdrs) -{ - return -ENOPROTOOPT; -} -#endif - - static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) { unsigned int dir; @@ -2663,7 +2473,6 @@ static pfkey_handler pfkey_funcs[SADB_MAX + 1] = { [SADB_X_SPDFLUSH] = pfkey_spdflush, [SADB_X_SPDSETIDX] = pfkey_spdadd, [SADB_X_SPDDELETE2] = pfkey_spdget, - [SADB_X_MIGRATE] = pfkey_migrate, }; static int pfkey_process(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr) @@ -3309,236 +3118,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL); } -#ifdef CONFIG_NET_KEY_MIGRATE -static int set_sadb_address(struct sk_buff *skb, int sasize, int type, - struct xfrm_selector *sel) -{ - struct sadb_address *addr; - struct sockaddr_in *sin; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - struct sockaddr_in6 *sin6; -#endif - addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); - addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; - addr->sadb_address_exttype = type; - addr->sadb_address_proto = sel->proto; - addr->sadb_address_reserved = 0; - - switch (type) { - case SADB_EXT_ADDRESS_SRC: - if (sel->family == AF_INET) { - addr->sadb_address_prefixlen = sel->prefixlen_s; - sin = (struct sockaddr_in *)(addr + 1); - sin->sin_family = AF_INET; - memcpy(&sin->sin_addr.s_addr, &sel->saddr, - sizeof(sin->sin_addr.s_addr)); - sin->sin_port = 0; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - else if (sel->family == AF_INET6) { - addr->sadb_address_prefixlen = sel->prefixlen_s; - sin6 = (struct sockaddr_in6 *)(addr + 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; - sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr, - sizeof(sin6->sin6_addr.s6_addr)); - } -#endif - break; - case SADB_EXT_ADDRESS_DST: - if (sel->family == AF_INET) { - addr->sadb_address_prefixlen = sel->prefixlen_d; - sin = (struct sockaddr_in *)(addr + 1); - sin->sin_family = AF_INET; - memcpy(&sin->sin_addr.s_addr, &sel->daddr, - sizeof(sin->sin_addr.s_addr)); - sin->sin_port = 0; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - else if (sel->family == AF_INET6) { - addr->sadb_address_prefixlen = sel->prefixlen_d; - sin6 = (struct sockaddr_in6 *)(addr + 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; - sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr, - sizeof(sin6->sin6_addr.s6_addr)); - } -#endif - break; - default: - return -EINVAL; - } - - return 0; -} - -static int set_ipsecrequest(struct sk_buff *skb, - uint8_t proto, uint8_t mode, int level, - uint32_t reqid, uint8_t family, - xfrm_address_t *src, xfrm_address_t *dst) -{ - struct sadb_x_ipsecrequest *rq; - struct sockaddr_in *sin; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - struct sockaddr_in6 *sin6; -#endif - int size_req; - - size_req = sizeof(struct sadb_x_ipsecrequest) + - pfkey_sockaddr_pair_size(family); - - rq = (struct sadb_x_ipsecrequest *)skb_put(skb, size_req); - memset(rq, 0, size_req); - rq->sadb_x_ipsecrequest_len = size_req; - rq->sadb_x_ipsecrequest_proto = proto; - rq->sadb_x_ipsecrequest_mode = mode; - rq->sadb_x_ipsecrequest_level = level; - rq->sadb_x_ipsecrequest_reqid = reqid; - - switch (family) { - case AF_INET: - sin = (struct sockaddr_in *)(rq + 1); - sin->sin_family = AF_INET; - memcpy(&sin->sin_addr.s_addr, src, - sizeof(sin->sin_addr.s_addr)); - sin++; - sin->sin_family = AF_INET; - memcpy(&sin->sin_addr.s_addr, dst, - sizeof(sin->sin_addr.s_addr)); - break; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - sin6 = (struct sockaddr_in6 *)(rq + 1); - sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; - sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - memcpy(&sin6->sin6_addr.s6_addr, src, - sizeof(sin6->sin6_addr.s6_addr)); - sin6++; - sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; - sin6->sin6_flowinfo = 0; - sin6->sin6_scope_id = 0; - memcpy(&sin6->sin6_addr.s6_addr, dst, - sizeof(sin6->sin6_addr.s6_addr)); - break; -#endif - default: - return -EINVAL; - } - - return 0; -} -#endif - -#ifdef CONFIG_NET_KEY_MIGRATE -static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_bundles) -{ - int i; - int sasize_sel; - int size = 0; - int size_pol = 0; - struct sk_buff *skb; - struct sadb_msg *hdr; - struct sadb_x_policy *pol; - struct xfrm_migrate *mp; - - if (type != XFRM_POLICY_TYPE_MAIN) - return 0; - - if (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH) - return -EINVAL; - - /* selector */ - sasize_sel = pfkey_sockaddr_size(sel->family); - if (!sasize_sel) - return -EINVAL; - size += (sizeof(struct sadb_address) + sasize_sel) * 2; - - /* policy info */ - size_pol += sizeof(struct sadb_x_policy); - - /* ipsecrequests */ - for (i = 0, mp = m; i < num_bundles; i++, mp++) { - /* old locator pair */ - size_pol += sizeof(struct sadb_x_ipsecrequest) + - pfkey_sockaddr_pair_size(mp->old_family); - /* new locator pair */ - size_pol += sizeof(struct sadb_x_ipsecrequest) + - pfkey_sockaddr_pair_size(mp->new_family); - } - - size += sizeof(struct sadb_msg) + size_pol; - - /* alloc buffer */ - skb = alloc_skb(size, GFP_ATOMIC); - if (skb == NULL) - return -ENOMEM; - - hdr = (struct sadb_msg *)skb_put(skb, sizeof(struct sadb_msg)); - hdr->sadb_msg_version = PF_KEY_V2; - hdr->sadb_msg_type = SADB_X_MIGRATE; - hdr->sadb_msg_satype = pfkey_proto2satype(m->proto); - hdr->sadb_msg_len = size / 8; - hdr->sadb_msg_errno = 0; - hdr->sadb_msg_reserved = 0; - hdr->sadb_msg_seq = 0; - hdr->sadb_msg_pid = 0; - - /* selector src */ - set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); - - /* selector dst */ - set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_DST, sel); - - /* policy information */ - pol = (struct sadb_x_policy *)skb_put(skb, sizeof(struct sadb_x_policy)); - pol->sadb_x_policy_len = size_pol / 8; - pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; - pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; - pol->sadb_x_policy_dir = dir + 1; - pol->sadb_x_policy_id = 0; - pol->sadb_x_policy_priority = 0; - - for (i = 0, mp = m; i < num_bundles; i++, mp++) { - /* old ipsecrequest */ - if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, - (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), - mp->reqid, mp->old_family, - &mp->old_saddr, &mp->old_daddr) < 0) { - return -EINVAL; - } - - /* new ipsecrequest */ - if (set_ipsecrequest(skb, mp->proto, mp->mode + 1, - (mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE), - mp->reqid, mp->new_family, - &mp->new_saddr, &mp->new_daddr) < 0) { - return -EINVAL; - } - } - - /* broadcast migrate message to sockets */ - pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL); - - return 0; -} -#else -static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_bundles) -{ - return -ENOPROTOOPT; -} -#endif - static int pfkey_sendmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg, size_t len) { @@ -3708,7 +3287,6 @@ static struct xfrm_mgr pfkeyv2_mgr = .compile_policy = pfkey_compile_policy, .new_mapping = pfkey_send_new_mapping, .notify_policy = pfkey_send_policy_notify, - .migrate = pfkey_send_migrate, }; static void __exit ipsec_pfkey_exit(void) diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index 748f7f00909a..80107d4909c5 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -235,19 +235,6 @@ config NF_CONNTRACK_PPTP To compile it as a module, choose M here. If unsure, say N. -config NF_CONNTRACK_SANE - tristate "SANE protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK - help - SANE is a protocol for remote access to scanners as implemented - by the 'saned' daemon. Like FTP, it uses separate control and - data connections. - - With this module you can support SANE on a connection tracking - firewall. - - To compile it as a module, choose M here. If unsure, say N. - config NF_CONNTRACK_SIP tristate "SIP protocol support (EXPERIMENTAL)" depends on EXPERIMENTAL && NF_CONNTRACK @@ -395,32 +382,6 @@ config NETFILTER_XT_TARGET_CONNSECMARK To compile it as a module, choose M here. If unsure, say N. -config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' - depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) - ---help--- - This option adds a `TCPMSS' target, which allows you to alter the - MSS value of TCP SYN packets, to control the maximum size for that - connection (usually limiting it to your outgoing interface's MTU - minus 40). - - This is used to overcome criminally braindead ISPs or servers which - block ICMP Fragmentation Needed packets. The symptoms of this - problem are that everything works fine from your Linux - firewall/router, but machines behind it can never exchange large - packets: - 1) Web browsers connect, then hang with no data received. - 2) Small mail works fine, but large emails hang. - 3) ssh works fine, but scp hangs after initial handshaking. - - Workaround: activate this option and add a rule to your firewall - configuration like: - - iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ - -j TCPMSS --clamp-mss-to-pmtu - - To compile it as a module, choose M here. If unsure, say N. - config NETFILTER_XT_MATCH_COMMENT tristate '"comment" match support' depends on NETFILTER_XTABLES diff --git a/trunk/net/netfilter/Makefile b/trunk/net/netfilter/Makefile index b2b5c7566b26..5dc5574f7e99 100644 --- a/trunk/net/netfilter/Makefile +++ b/trunk/net/netfilter/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_NF_CONNTRACK_H323) += nf_conntrack_h323.o obj-$(CONFIG_NF_CONNTRACK_IRC) += nf_conntrack_irc.o obj-$(CONFIG_NF_CONNTRACK_NETBIOS_NS) += nf_conntrack_netbios_ns.o obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_conntrack_pptp.o -obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o @@ -45,7 +44,6 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o -obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o # matches diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 6fccdcf43e08..626b0011dd89 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -60,9 +60,12 @@ static DEFINE_RWLOCK(tcp_lock); If it's non-zero, we mark only out of window RST segments as INVALID. */ int nf_ct_tcp_be_liberal __read_mostly = 0; -/* If it is set to zero, we disable picking up already established +/* When connection is picked up from the middle, how many packets are required + to pass in each direction when we assume we are in sync - if any side uses + window scaling, we lost the game. + If it is set to zero, we disable picking up already established connections. */ -int nf_ct_tcp_loose __read_mostly = 1; +int nf_ct_tcp_loose __read_mostly = 3; /* Max number of the retransmitted packets without receiving an (acceptable) ACK from the destination. If this number is reached, a shorter timer @@ -647,10 +650,11 @@ static int tcp_in_window(struct ip_ct_tcp *state, before(sack, receiver->td_end + 1), after(ack, receiver->td_end - MAXACKWINDOW(sender))); - if (before(seq, sender->td_maxend + 1) && - after(end, sender->td_end - receiver->td_maxwin - 1) && - before(sack, receiver->td_end + 1) && - after(ack, receiver->td_end - MAXACKWINDOW(sender))) { + if (sender->loose || receiver->loose || + (before(seq, sender->td_maxend + 1) && + after(end, sender->td_end - receiver->td_maxwin - 1) && + before(sack, receiver->td_end + 1) && + after(ack, receiver->td_end - MAXACKWINDOW(sender)))) { /* * Take into account window scaling (RFC 1323). */ @@ -695,13 +699,15 @@ static int tcp_in_window(struct ip_ct_tcp *state, state->retrans = 0; } } + /* + * Close the window of disabled window tracking :-) + */ + if (sender->loose) + sender->loose--; + res = 1; } else { - res = 0; - if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || - nf_ct_tcp_be_liberal) - res = 1; - if (!res && LOG_INVALID(IPPROTO_TCP)) + if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_tcp: %s ", before(seq, sender->td_maxend + 1) ? @@ -712,6 +718,8 @@ static int tcp_in_window(struct ip_ct_tcp *state, : "ACK is over the upper bound (ACKed data not seen yet)" : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); + + res = nf_ct_tcp_be_liberal; } DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " @@ -1055,6 +1063,8 @@ static int tcp_new(struct nf_conn *conntrack, tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]); conntrack->proto.tcp.seen[1].flags = 0; + conntrack->proto.tcp.seen[0].loose = + conntrack->proto.tcp.seen[1].loose = 0; } else if (nf_ct_tcp_loose == 0) { /* Don't try to pick up connections. */ return 0; @@ -1075,11 +1085,11 @@ static int tcp_new(struct nf_conn *conntrack, conntrack->proto.tcp.seen[0].td_maxwin; conntrack->proto.tcp.seen[0].td_scale = 0; - /* We assume SACK and liberal window checking to handle - * window scaling */ + /* We assume SACK. Should we assume window scaling too? */ conntrack->proto.tcp.seen[0].flags = - conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM | - IP_CT_TCP_FLAG_BE_LIBERAL; + conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM; + conntrack->proto.tcp.seen[0].loose = + conntrack->proto.tcp.seen[1].loose = nf_ct_tcp_loose; } conntrack->proto.tcp.seen[1].td_end = 0; diff --git a/trunk/net/netfilter/nf_conntrack_sane.c b/trunk/net/netfilter/nf_conntrack_sane.c deleted file mode 100644 index eb2d1dc46d45..000000000000 --- a/trunk/net/netfilter/nf_conntrack_sane.c +++ /dev/null @@ -1,242 +0,0 @@ -/* SANE connection tracking helper - * (SANE = Scanner Access Now Easy) - * For documentation about the SANE network protocol see - * http://www.sane-project.org/html/doc015.html - */ - -/* Copyright (C) 2007 Red Hat, Inc. - * Author: Michal Schmidt - * Based on the FTP conntrack helper (net/netfilter/nf_conntrack_ftp.c): - * (C) 1999-2001 Paul `Rusty' Russell - * (C) 2002-2004 Netfilter Core Team - * (C) 2003,2004 USAGI/WIDE Project - * (C) 2003 Yasuyuki Kozakai @USAGI - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michal Schmidt "); -MODULE_DESCRIPTION("SANE connection tracking helper"); - -static char *sane_buffer; - -static DEFINE_SPINLOCK(nf_sane_lock); - -#define MAX_PORTS 8 -static u_int16_t ports[MAX_PORTS]; -static unsigned int ports_c; -module_param_array(ports, ushort, &ports_c, 0400); - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - -struct sane_request { - __be32 RPC_code; -#define SANE_NET_START 7 /* RPC code */ - - __be32 handle; -}; - -struct sane_reply_net_start { - __be32 status; -#define SANE_STATUS_SUCCESS 0 - - __be16 zero; - __be16 port; - /* other fields aren't interesting for conntrack */ -}; - -static int help(struct sk_buff **pskb, - unsigned int protoff, - struct nf_conn *ct, - enum ip_conntrack_info ctinfo) -{ - unsigned int dataoff, datalen; - struct tcphdr _tcph, *th; - char *sb_ptr; - int ret = NF_ACCEPT; - int dir = CTINFO2DIR(ctinfo); - struct nf_ct_sane_master *ct_sane_info; - struct nf_conntrack_expect *exp; - struct nf_conntrack_tuple *tuple; - struct sane_request *req; - struct sane_reply_net_start *reply; - int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; - - ct_sane_info = &nfct_help(ct)->help.ct_sane_info; - /* Until there's been traffic both ways, don't look in packets. */ - if (ctinfo != IP_CT_ESTABLISHED && - ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) - return NF_ACCEPT; - - /* Not a full tcp header? */ - th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph); - if (th == NULL) - return NF_ACCEPT; - - /* No data? */ - dataoff = protoff + th->doff * 4; - if (dataoff >= (*pskb)->len) - return NF_ACCEPT; - - datalen = (*pskb)->len - dataoff; - - spin_lock_bh(&nf_sane_lock); - sb_ptr = skb_header_pointer(*pskb, dataoff, datalen, sane_buffer); - BUG_ON(sb_ptr == NULL); - - if (dir == IP_CT_DIR_ORIGINAL) { - if (datalen != sizeof(struct sane_request)) - goto out; - - req = (struct sane_request *)sb_ptr; - if (req->RPC_code != htonl(SANE_NET_START)) { - /* Not an interesting command */ - ct_sane_info->state = SANE_STATE_NORMAL; - goto out; - } - - /* We're interested in the next reply */ - ct_sane_info->state = SANE_STATE_START_REQUESTED; - goto out; - } - - /* Is it a reply to an uninteresting command? */ - if (ct_sane_info->state != SANE_STATE_START_REQUESTED) - goto out; - - /* It's a reply to SANE_NET_START. */ - ct_sane_info->state = SANE_STATE_NORMAL; - - if (datalen < sizeof(struct sane_reply_net_start)) { - DEBUGP("nf_ct_sane: NET_START reply too short\n"); - goto out; - } - - reply = (struct sane_reply_net_start *)sb_ptr; - if (reply->status != htonl(SANE_STATUS_SUCCESS)) { - /* saned refused the command */ - DEBUGP("nf_ct_sane: unsuccessful SANE_STATUS = %u\n", - ntohl(reply->status)); - goto out; - } - - /* Invalid saned reply? Ignore it. */ - if (reply->zero != 0) - goto out; - - exp = nf_conntrack_expect_alloc(ct); - if (exp == NULL) { - ret = NF_DROP; - goto out; - } - - tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - nf_conntrack_expect_init(exp, family, - &tuple->src.u3, &tuple->dst.u3, - IPPROTO_TCP, - NULL, &reply->port); - - DEBUGP("nf_ct_sane: expect: "); - NF_CT_DUMP_TUPLE(&exp->tuple); - NF_CT_DUMP_TUPLE(&exp->mask); - - /* Can't expect this? Best to drop packet now. */ - if (nf_conntrack_expect_related(exp) != 0) - ret = NF_DROP; - - nf_conntrack_expect_put(exp); - -out: - spin_unlock_bh(&nf_sane_lock); - return ret; -} - -static struct nf_conntrack_helper sane[MAX_PORTS][2]; -static char sane_names[MAX_PORTS][2][sizeof("sane-65535")]; - -/* don't make this __exit, since it's called from __init ! */ -static void nf_conntrack_sane_fini(void) -{ - int i, j; - - for (i = 0; i < ports_c; i++) { - for (j = 0; j < 2; j++) { - DEBUGP("nf_ct_sane: unregistering helper for pf: %d " - "port: %d\n", - sane[i][j].tuple.src.l3num, ports[i]); - nf_conntrack_helper_unregister(&sane[i][j]); - } - } - - kfree(sane_buffer); -} - -static int __init nf_conntrack_sane_init(void) -{ - int i, j = -1, ret = 0; - char *tmpname; - - sane_buffer = kmalloc(65536, GFP_KERNEL); - if (!sane_buffer) - return -ENOMEM; - - if (ports_c == 0) - ports[ports_c++] = SANE_PORT; - - /* FIXME should be configurable whether IPv4 and IPv6 connections - are tracked or not - YK */ - for (i = 0; i < ports_c; i++) { - sane[i][0].tuple.src.l3num = PF_INET; - sane[i][1].tuple.src.l3num = PF_INET6; - for (j = 0; j < 2; j++) { - sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); - sane[i][j].tuple.dst.protonum = IPPROTO_TCP; - sane[i][j].mask.src.u.tcp.port = 0xFFFF; - sane[i][j].mask.dst.protonum = 0xFF; - sane[i][j].max_expected = 1; - sane[i][j].timeout = 5 * 60; /* 5 Minutes */ - sane[i][j].me = THIS_MODULE; - sane[i][j].help = help; - tmpname = &sane_names[i][j][0]; - if (ports[i] == SANE_PORT) - sprintf(tmpname, "sane"); - else - sprintf(tmpname, "sane-%d", ports[i]); - sane[i][j].name = tmpname; - - DEBUGP("nf_ct_sane: registering helper for pf: %d " - "port: %d\n", - sane[i][j].tuple.src.l3num, ports[i]); - ret = nf_conntrack_helper_register(&sane[i][j]); - if (ret) { - printk(KERN_ERR "nf_ct_sane: failed to " - "register helper for pf: %d port: %d\n", - sane[i][j].tuple.src.l3num, ports[i]); - nf_conntrack_sane_fini(); - return ret; - } - } - } - - return 0; -} - -module_init(nf_conntrack_sane_init); -module_exit(nf_conntrack_sane_fini); diff --git a/trunk/net/netfilter/xt_CLASSIFY.c b/trunk/net/netfilter/xt_CLASSIFY.c index 195e92990da7..50de965bb104 100644 --- a/trunk/net/netfilter/xt_CLASSIFY.c +++ b/trunk/net/netfilter/xt_CLASSIFY.c @@ -33,7 +33,9 @@ target(struct sk_buff **pskb, { const struct xt_classify_target_info *clinfo = targinfo; - (*pskb)->priority = clinfo->priority; + if ((*pskb)->priority != clinfo->priority) + (*pskb)->priority = clinfo->priority; + return XT_CONTINUE; } diff --git a/trunk/net/netfilter/xt_CONNMARK.c b/trunk/net/netfilter/xt_CONNMARK.c index 795c058b16a5..0534bfa65cce 100644 --- a/trunk/net/netfilter/xt_CONNMARK.c +++ b/trunk/net/netfilter/xt_CONNMARK.c @@ -61,7 +61,7 @@ target(struct sk_buff **pskb, #else nf_conntrack_event_cache(IPCT_MARK, *pskb); #endif - } + } break; case XT_CONNMARK_SAVE: newmark = (*ctmark & ~markinfo->mask) | @@ -78,7 +78,8 @@ target(struct sk_buff **pskb, case XT_CONNMARK_RESTORE: mark = (*pskb)->mark; diff = (*ctmark ^ mark) & markinfo->mask; - (*pskb)->mark = mark ^ diff; + if (diff != 0) + (*pskb)->mark = mark ^ diff; break; } } diff --git a/trunk/net/netfilter/xt_CONNSECMARK.c b/trunk/net/netfilter/xt_CONNSECMARK.c index 1ab0db641f96..a3fe3c334b09 100644 --- a/trunk/net/netfilter/xt_CONNSECMARK.c +++ b/trunk/net/netfilter/xt_CONNSECMARK.c @@ -41,7 +41,8 @@ static void secmark_save(struct sk_buff *skb) connsecmark = nf_ct_get_secmark(skb, &ctinfo); if (connsecmark && !*connsecmark) - *connsecmark = skb->secmark; + if (*connsecmark != skb->secmark) + *connsecmark = skb->secmark; } } @@ -57,7 +58,8 @@ static void secmark_restore(struct sk_buff *skb) connsecmark = nf_ct_get_secmark(skb, &ctinfo); if (connsecmark && *connsecmark) - skb->secmark = *connsecmark; + if (skb->secmark != *connsecmark) + skb->secmark = *connsecmark; } } diff --git a/trunk/net/netfilter/xt_MARK.c b/trunk/net/netfilter/xt_MARK.c index cfc45af357d5..0b48547e8d64 100644 --- a/trunk/net/netfilter/xt_MARK.c +++ b/trunk/net/netfilter/xt_MARK.c @@ -31,7 +31,9 @@ target_v0(struct sk_buff **pskb, { const struct xt_mark_target_info *markinfo = targinfo; - (*pskb)->mark = markinfo->mark; + if((*pskb)->mark != markinfo->mark) + (*pskb)->mark = markinfo->mark; + return XT_CONTINUE; } @@ -60,7 +62,9 @@ target_v1(struct sk_buff **pskb, break; } - (*pskb)->mark = mark; + if((*pskb)->mark != mark) + (*pskb)->mark = mark; + return XT_CONTINUE; } diff --git a/trunk/net/netfilter/xt_SECMARK.c b/trunk/net/netfilter/xt_SECMARK.c index f1131c3a9db5..add752196290 100644 --- a/trunk/net/netfilter/xt_SECMARK.c +++ b/trunk/net/netfilter/xt_SECMARK.c @@ -47,7 +47,9 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in, BUG(); } - (*pskb)->secmark = secmark; + if ((*pskb)->secmark != secmark) + (*pskb)->secmark = secmark; + return XT_CONTINUE; } diff --git a/trunk/net/netfilter/xt_TCPMSS.c b/trunk/net/netfilter/xt_TCPMSS.c deleted file mode 100644 index db7e38c08de2..000000000000 --- a/trunk/net/netfilter/xt_TCPMSS.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * This is a module which is used for setting the MSS option in TCP packets. - * - * Copyright (C) 2000 Marc Boucher - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Marc Boucher "); -MODULE_DESCRIPTION("x_tables TCP MSS modification module"); -MODULE_ALIAS("ipt_TCPMSS"); -MODULE_ALIAS("ip6t_TCPMSS"); - -static inline unsigned int -optlen(const u_int8_t *opt, unsigned int offset) -{ - /* Beware zero-length options: make finite progress */ - if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0) - return 1; - else - return opt[offset+1]; -} - -static int -tcpmss_mangle_packet(struct sk_buff **pskb, - const struct xt_tcpmss_info *info, - unsigned int tcphoff, - unsigned int minlen) -{ - struct tcphdr *tcph; - unsigned int tcplen, i; - __be16 oldval; - u16 newmss; - u8 *opt; - - if (!skb_make_writable(pskb, (*pskb)->len)) - return -1; - - tcplen = (*pskb)->len - tcphoff; - tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff); - - /* Since it passed flags test in tcp match, we know it is is - not a fragment, and has data >= tcp header length. SYN - packets should not contain data: if they did, then we risk - running over MTU, sending Frag Needed and breaking things - badly. --RR */ - if (tcplen != tcph->doff*4) { - if (net_ratelimit()) - printk(KERN_ERR "xt_TCPMSS: bad length (%u bytes)\n", - (*pskb)->len); - return -1; - } - - if (info->mss == XT_TCPMSS_CLAMP_PMTU) { - if (dst_mtu((*pskb)->dst) <= minlen) { - if (net_ratelimit()) - printk(KERN_ERR "xt_TCPMSS: " - "unknown or invalid path-MTU (%u)\n", - dst_mtu((*pskb)->dst)); - return -1; - } - newmss = dst_mtu((*pskb)->dst) - minlen; - } else - newmss = info->mss; - - opt = (u_int8_t *)tcph; - for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) { - if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS && - opt[i+1] == TCPOLEN_MSS) { - u_int16_t oldmss; - - oldmss = (opt[i+2] << 8) | opt[i+3]; - - if (info->mss == XT_TCPMSS_CLAMP_PMTU && - oldmss <= newmss) - return 0; - - opt[i+2] = (newmss & 0xff00) >> 8; - opt[i+3] = (newmss & 0x00ff); - - nf_proto_csum_replace2(&tcph->check, *pskb, - htons(oldmss), htons(newmss), 0); - return 0; - } - } - - /* - * MSS Option not found ?! add it.. - */ - if (skb_tailroom((*pskb)) < TCPOLEN_MSS) { - struct sk_buff *newskb; - - newskb = skb_copy_expand(*pskb, skb_headroom(*pskb), - TCPOLEN_MSS, GFP_ATOMIC); - if (!newskb) - return -1; - kfree_skb(*pskb); - *pskb = newskb; - tcph = (struct tcphdr *)((*pskb)->nh.raw + tcphoff); - } - - skb_put((*pskb), TCPOLEN_MSS); - - opt = (u_int8_t *)tcph + sizeof(struct tcphdr); - memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); - - nf_proto_csum_replace2(&tcph->check, *pskb, - htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1); - opt[0] = TCPOPT_MSS; - opt[1] = TCPOLEN_MSS; - opt[2] = (newmss & 0xff00) >> 8; - opt[3] = (newmss & 0x00ff); - - nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0); - - oldval = ((__be16 *)tcph)[6]; - tcph->doff += TCPOLEN_MSS/4; - nf_proto_csum_replace2(&tcph->check, *pskb, - oldval, ((__be16 *)tcph)[6], 0); - return TCPOLEN_MSS; -} - -static unsigned int -xt_tcpmss_target4(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const struct xt_target *target, - const void *targinfo) -{ - struct iphdr *iph = (*pskb)->nh.iph; - __be16 newlen; - int ret; - - ret = tcpmss_mangle_packet(pskb, targinfo, iph->ihl * 4, - sizeof(*iph) + sizeof(struct tcphdr)); - if (ret < 0) - return NF_DROP; - if (ret > 0) { - iph = (*pskb)->nh.iph; - newlen = htons(ntohs(iph->tot_len) + ret); - nf_csum_replace2(&iph->check, iph->tot_len, newlen); - iph->tot_len = newlen; - } - return XT_CONTINUE; -} - -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) -static unsigned int -xt_tcpmss_target6(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const struct xt_target *target, - const void *targinfo) -{ - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h; - u8 nexthdr; - int tcphoff; - int ret; - - nexthdr = ipv6h->nexthdr; - tcphoff = ipv6_skip_exthdr(*pskb, sizeof(*ipv6h), &nexthdr); - if (tcphoff < 0) { - WARN_ON(1); - return NF_DROP; - } - ret = tcpmss_mangle_packet(pskb, targinfo, tcphoff, - sizeof(*ipv6h) + sizeof(struct tcphdr)); - if (ret < 0) - return NF_DROP; - if (ret > 0) { - ipv6h = (*pskb)->nh.ipv6h; - ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret); - } - return XT_CONTINUE; -} -#endif - -#define TH_SYN 0x02 - -/* Must specify -p tcp --syn */ -static inline int find_syn_match(const struct xt_entry_match *m) -{ - const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data; - - if (strcmp(m->u.kernel.match->name, "tcp") == 0 && - tcpinfo->flg_cmp & TH_SYN && - !(tcpinfo->invflags & XT_TCP_INV_FLAGS)) - return 1; - - return 0; -} - -static int -xt_tcpmss_checkentry4(const char *tablename, - const void *entry, - const struct xt_target *target, - void *targinfo, - unsigned int hook_mask) -{ - const struct xt_tcpmss_info *info = targinfo; - const struct ipt_entry *e = entry; - - if (info->mss == XT_TCPMSS_CLAMP_PMTU && - (hook_mask & ~((1 << NF_IP_FORWARD) | - (1 << NF_IP_LOCAL_OUT) | - (1 << NF_IP_POST_ROUTING))) != 0) { - printk("xt_TCPMSS: path-MTU clamping only supported in " - "FORWARD, OUTPUT and POSTROUTING hooks\n"); - return 0; - } - if (IPT_MATCH_ITERATE(e, find_syn_match)) - return 1; - printk("xt_TCPMSS: Only works on TCP SYN packets\n"); - return 0; -} - -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) -static int -xt_tcpmss_checkentry6(const char *tablename, - const void *entry, - const struct xt_target *target, - void *targinfo, - unsigned int hook_mask) -{ - const struct xt_tcpmss_info *info = targinfo; - const struct ip6t_entry *e = entry; - - if (info->mss == XT_TCPMSS_CLAMP_PMTU && - (hook_mask & ~((1 << NF_IP6_FORWARD) | - (1 << NF_IP6_LOCAL_OUT) | - (1 << NF_IP6_POST_ROUTING))) != 0) { - printk("xt_TCPMSS: path-MTU clamping only supported in " - "FORWARD, OUTPUT and POSTROUTING hooks\n"); - return 0; - } - if (IP6T_MATCH_ITERATE(e, find_syn_match)) - return 1; - printk("xt_TCPMSS: Only works on TCP SYN packets\n"); - return 0; -} -#endif - -static struct xt_target xt_tcpmss_reg[] = { - { - .family = AF_INET, - .name = "TCPMSS", - .checkentry = xt_tcpmss_checkentry4, - .target = xt_tcpmss_target4, - .targetsize = sizeof(struct xt_tcpmss_info), - .proto = IPPROTO_TCP, - .me = THIS_MODULE, - }, -#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) - { - .family = AF_INET6, - .name = "TCPMSS", - .checkentry = xt_tcpmss_checkentry6, - .target = xt_tcpmss_target6, - .targetsize = sizeof(struct xt_tcpmss_info), - .proto = IPPROTO_TCP, - .me = THIS_MODULE, - }, -#endif -}; - -static int __init xt_tcpmss_init(void) -{ - return xt_register_targets(xt_tcpmss_reg, ARRAY_SIZE(xt_tcpmss_reg)); -} - -static void __exit xt_tcpmss_fini(void) -{ - xt_unregister_targets(xt_tcpmss_reg, ARRAY_SIZE(xt_tcpmss_reg)); -} - -module_init(xt_tcpmss_init); -module_exit(xt_tcpmss_fini); diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index bd1f7a2048d6..f28bf69d3d42 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -414,7 +414,6 @@ hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst, switch (nexthdr) { case IPPROTO_TCP: case IPPROTO_UDP: - case IPPROTO_UDPLITE: case IPPROTO_SCTP: case IPPROTO_DCCP: ports = skb_header_pointer(skb, protoff, sizeof(_ports), diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index a6fa48788e8f..6dc01bdeb76b 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -201,8 +200,7 @@ struct packet_sock { #endif struct packet_type prot_hook; spinlock_t bind_lock; - unsigned int running:1, /* prot_hook is attached*/ - auxdata:1; + char running; /* prot_hook is attached*/ int ifindex; /* bound device */ __be16 num; #ifdef CONFIG_PACKET_MULTICAST @@ -216,16 +214,6 @@ struct packet_sock { #endif }; -struct packet_skb_cb { - unsigned int origlen; - union { - struct sockaddr_pkt pkt; - struct sockaddr_ll ll; - } sa; -}; - -#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb)) - #ifdef CONFIG_PACKET_MMAP static inline char *packet_lookup_frame(struct packet_sock *po, unsigned int position) @@ -305,7 +293,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct /* drop conntrack reference */ nf_reset(skb); - spkt = &PACKET_SKB_CB(skb)->sa.pkt; + spkt = (struct sockaddr_pkt*)skb->cb; skb_push(skb, skb->data-skb->mac.raw); @@ -524,10 +512,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet skb = nskb; } - BUILD_BUG_ON(sizeof(*PACKET_SKB_CB(skb)) + MAX_ADDR_LEN - 8 > - sizeof(skb->cb)); - - sll = &PACKET_SKB_CB(skb)->sa.ll; + sll = (struct sockaddr_ll*)skb->cb; sll->sll_family = AF_PACKET; sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; @@ -538,8 +523,6 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet if (dev->hard_header_parse) sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); - PACKET_SKB_CB(skb)->origlen = skb->len; - if (pskb_trim(skb, snaplen)) goto drop_n_acct; @@ -599,12 +582,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe else if (skb->pkt_type == PACKET_OUTGOING) { /* Special case: outgoing packets have ll header at head */ skb_pull(skb, skb->nh.raw - skb->data); + if (skb->ip_summed == CHECKSUM_PARTIAL) + status |= TP_STATUS_CSUMNOTREADY; } } - if (skb->ip_summed == CHECKSUM_PARTIAL) - status |= TP_STATUS_CSUMNOTREADY; - snaplen = skb->len; res = run_filter(skb, sk, snaplen); @@ -1110,7 +1092,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, * it in now. */ - sll = &PACKET_SKB_CB(skb)->sa.ll; + sll = (struct sockaddr_ll*)skb->cb; if (sock->type == SOCK_PACKET) msg->msg_namelen = sizeof(struct sockaddr_pkt); else @@ -1135,22 +1117,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, sock_recv_timestamp(msg, sk, skb); if (msg->msg_name) - memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, - msg->msg_namelen); - - if (pkt_sk(sk)->auxdata) { - struct tpacket_auxdata aux; - - aux.tp_status = TP_STATUS_USER; - if (skb->ip_summed == CHECKSUM_PARTIAL) - aux.tp_status |= TP_STATUS_CSUMNOTREADY; - aux.tp_len = PACKET_SKB_CB(skb)->origlen; - aux.tp_snaplen = skb->len; - aux.tp_mac = 0; - aux.tp_net = skb->nh.raw - skb->data; - - put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); - } + memcpy(msg->msg_name, skb->cb, msg->msg_namelen); /* * Free or return the buffer as appropriate. Again this @@ -1350,7 +1317,6 @@ static int packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk = sock->sk; - struct packet_sock *po = pkt_sk(sk); int ret; if (level != SOL_PACKET) @@ -1403,18 +1369,6 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv return 0; } #endif - case PACKET_AUXDATA: - { - int val; - - if (optlen < sizeof(val)) - return -EINVAL; - if (copy_from_user(&val, optval, sizeof(val))) - return -EFAULT; - - po->auxdata = !!val; - return 0; - } default: return -ENOPROTOOPT; } @@ -1424,11 +1378,8 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { int len; - int val; struct sock *sk = sock->sk; struct packet_sock *po = pkt_sk(sk); - void *data; - struct tpacket_stats st; if (level != SOL_PACKET) return -ENOPROTOOPT; @@ -1441,6 +1392,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, switch(optname) { case PACKET_STATISTICS: + { + struct tpacket_stats st; + if (len > sizeof(struct tpacket_stats)) len = sizeof(struct tpacket_stats); spin_lock_bh(&sk->sk_receive_queue.lock); @@ -1449,23 +1403,16 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, spin_unlock_bh(&sk->sk_receive_queue.lock); st.tp_packets += st.tp_drops; - data = &st; - break; - case PACKET_AUXDATA: - if (len > sizeof(int)) - len = sizeof(int); - val = po->auxdata; - - data = &val; + if (copy_to_user(optval, &st, len)) + return -EFAULT; break; + } default: return -ENOPROTOOPT; } if (put_user(len, optlen)) return -EFAULT; - if (copy_to_user(optval, data, len)) - return -EFAULT; return 0; } diff --git a/trunk/net/sched/act_ipt.c b/trunk/net/sched/act_ipt.c index 4c68c718f5ec..01e69138578d 100644 --- a/trunk/net/sched/act_ipt.c +++ b/trunk/net/sched/act_ipt.c @@ -52,7 +52,7 @@ static struct tcf_hashinfo ipt_hash_info = { static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) { - struct xt_target *target; + struct ipt_target *target; int ret = 0; target = xt_request_find_target(AF_INET, t->u.user.name, diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 3b6e6a780927..bc116bd6937c 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -209,7 +209,7 @@ static void dev_watchdog(unsigned long arg) dev->name); dev->tx_timeout(dev); } - if (!mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + dev->watchdog_timeo))) + if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo)) dev_hold(dev); } } diff --git a/trunk/net/sched/sch_prio.c b/trunk/net/sched/sch_prio.c index 000e043ebd62..2567b4c96c1e 100644 --- a/trunk/net/sched/sch_prio.c +++ b/trunk/net/sched/sch_prio.c @@ -372,20 +372,6 @@ static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff * return 0; } -static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl, - struct gnet_dump *d) -{ - struct prio_sched_data *q = qdisc_priv(sch); - struct Qdisc *cl_q; - - cl_q = q->queues[cl - 1]; - if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 || - gnet_stats_copy_queue(d, &cl_q->qstats) < 0) - return -1; - - return 0; -} - static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg) { struct prio_sched_data *q = qdisc_priv(sch); @@ -428,7 +414,6 @@ static struct Qdisc_class_ops prio_class_ops = { .bind_tcf = prio_bind, .unbind_tcf = prio_put, .dump = prio_dump_class, - .dump_stats = prio_dump_class_stats, }; static struct Qdisc_ops prio_qdisc_ops = { diff --git a/trunk/net/sched/sch_sfq.c b/trunk/net/sched/sch_sfq.c index 82844801e421..459cda258a5c 100644 --- a/trunk/net/sched/sch_sfq.c +++ b/trunk/net/sched/sch_sfq.c @@ -143,7 +143,6 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP || - iph->protocol == IPPROTO_UDPLITE || iph->protocol == IPPROTO_SCTP || iph->protocol == IPPROTO_DCCP || iph->protocol == IPPROTO_ESP)) @@ -157,7 +156,6 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) h2 = iph->saddr.s6_addr32[3]^iph->nexthdr; if (iph->nexthdr == IPPROTO_TCP || iph->nexthdr == IPPROTO_UDP || - iph->nexthdr == IPPROTO_UDPLITE || iph->nexthdr == IPPROTO_SCTP || iph->nexthdr == IPPROTO_DCCP || iph->nexthdr == IPPROTO_ESP) diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 5f374e1ff526..4e396312f8d5 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -407,11 +407,24 @@ int sock_map_fd(struct socket *sock) static struct socket *sock_from_file(struct file *file, int *err) { + struct inode *inode; + struct socket *sock; + if (file->f_op == &socket_file_ops) return file->private_data; /* set in sock_map_fd */ - *err = -ENOTSOCK; - return NULL; + inode = file->f_path.dentry->d_inode; + if (!S_ISSOCK(inode->i_mode)) { + *err = -ENOTSOCK; + return NULL; + } + + sock = SOCKET_I(inode); + if (sock->file != file) { + printk(KERN_ERR "socki_lookup: socket file changed!\n"); + sock->file = file; + } + return sock; } /** @@ -1514,9 +1527,8 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len, struct file *sock_file; sock_file = fget_light(fd, &fput_needed); - err = -EBADF; if (!sock_file) - goto out; + return -EBADF; sock = sock_from_file(sock_file, &err); if (!sock) @@ -1543,7 +1555,6 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len, out_put: fput_light(sock_file, fput_needed); -out: return err; } @@ -1575,13 +1586,12 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size, int fput_needed; sock_file = fget_light(fd, &fput_needed); - err = -EBADF; if (!sock_file) - goto out; + return -EBADF; sock = sock_from_file(sock_file, &err); if (!sock) - goto out_put; + goto out; msg.msg_control = NULL; msg.msg_controllen = 0; @@ -1600,9 +1610,8 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size, if (err2 < 0) err = err2; } -out_put: - fput_light(sock_file, fput_needed); out: + fput_light(sock_file, fput_needed); return err; } diff --git a/trunk/net/wanrouter/wanmain.c b/trunk/net/wanrouter/wanmain.c index 4d90a179aeda..769cdd62c1bb 100644 --- a/trunk/net/wanrouter/wanmain.c +++ b/trunk/net/wanrouter/wanmain.c @@ -86,8 +86,8 @@ static int wanrouter_device_del_if(struct wan_device *wandev, static struct wan_device *wanrouter_find_device(char *name); static int wanrouter_delete_interface(struct wan_device *wandev, char *name); -static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); -static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); +void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); +void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags); @@ -104,8 +104,8 @@ struct wan_device* wanrouter_router_devlist; /* list of registered devices */ * Organize Unique Identifiers for encapsulation/decapsulation */ -#if 0 static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 }; +#if 0 static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 }; #endif @@ -246,8 +246,6 @@ int unregister_wan_device(char *name) return 0; } -#if 0 - /* * Encapsulate packet. * @@ -343,7 +341,6 @@ __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev) return ethertype; } -#endif /* 0 */ /* * WAN device IOCTL. @@ -802,19 +799,23 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name) return 0; } -static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) +void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) { spin_lock_irqsave(lock, *smp_flags); } -static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) +void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags) { spin_unlock_irqrestore(lock, *smp_flags); } EXPORT_SYMBOL(register_wan_device); EXPORT_SYMBOL(unregister_wan_device); +EXPORT_SYMBOL(wanrouter_encapsulate); +EXPORT_SYMBOL(wanrouter_type_trans); +EXPORT_SYMBOL(lock_adapter_irq); +EXPORT_SYMBOL(unlock_adapter_irq); MODULE_LICENSE("GPL"); diff --git a/trunk/net/x25/Makefile b/trunk/net/x25/Makefile index a2c34ab6f194..587a71aa411d 100644 --- a/trunk/net/x25/Makefile +++ b/trunk/net/x25/Makefile @@ -6,5 +6,5 @@ obj-$(CONFIG_X25) += x25.o x25-y := af_x25.o x25_dev.o x25_facilities.o x25_in.o \ x25_link.o x25_out.o x25_route.o x25_subr.o \ - x25_timer.o x25_proc.o x25_forward.o + x25_timer.o x25_proc.o x25-$(CONFIG_SYSCTL) += sysctl_net_x25.o diff --git a/trunk/net/x25/af_x25.c b/trunk/net/x25/af_x25.c index b37d894358ec..b5c80b189902 100644 --- a/trunk/net/x25/af_x25.c +++ b/trunk/net/x25/af_x25.c @@ -63,7 +63,6 @@ int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22; int sysctl_x25_clear_request_timeout = X25_DEFAULT_T23; int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2; -int sysctl_x25_forward = 0; HLIST_HEAD(x25_list); DEFINE_RWLOCK(x25_list_lock); @@ -847,7 +846,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, struct x25_address source_addr, dest_addr; struct x25_facilities facilities; struct x25_dte_facilities dte_facilities; - int len, addr_len, rc; + int len, rc; /* * Remove the LCI and frame type. @@ -858,8 +857,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, * Extract the X.25 addresses and convert them to ASCII strings, * and remove them. */ - addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); - skb_pull(skb, addr_len); + skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); /* * Get the length of the facilities, skip past them for the moment @@ -875,28 +873,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, sk = x25_find_listener(&source_addr,skb); skb_push(skb,len); - if (sk != NULL && sk_acceptq_is_full(sk)) { - goto out_sock_put; - } - /* - * We dont have any listeners for this incoming call. - * Try forwarding it. + * We can't accept the Call Request. */ - if (sk == NULL) { - skb_push(skb, addr_len + X25_STD_MIN_LEN); - if (sysctl_x25_forward && - x25_forward_call(&dest_addr, nb, skb, lci) > 0) - { - /* Call was forwarded, dont process it any more */ - kfree_skb(skb); - rc = 1; - goto out; - } else { - /* No listeners, can't forward, clear the call */ - goto out_clear_request; - } - } + if (sk == NULL || sk_acceptq_is_full(sk)) + goto out_clear_request; /* * Try to reach a compromise on the requested facilities. @@ -1617,9 +1598,6 @@ void x25_kill_by_neigh(struct x25_neigh *nb) x25_disconnect(s, ENETUNREACH, 0, 0); write_unlock_bh(&x25_list_lock); - - /* Remove any related forwards */ - x25_clear_forward_by_dev(nb->dev); } static int __init x25_init(void) diff --git a/trunk/net/x25/sysctl_net_x25.c b/trunk/net/x25/sysctl_net_x25.c index 2b2e7fd689f3..aabda59c824e 100644 --- a/trunk/net/x25/sysctl_net_x25.c +++ b/trunk/net/x25/sysctl_net_x25.c @@ -73,14 +73,6 @@ static struct ctl_table x25_table[] = { .extra1 = &min_timer, .extra2 = &max_timer, }, - { - .ctl_name = NET_X25_FORWARD, - .procname = "x25_forward", - .data = &sysctl_x25_forward, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, { 0, }, }; diff --git a/trunk/net/x25/x25_dev.c b/trunk/net/x25/x25_dev.c index f099fd6a7c0e..328d80f000ad 100644 --- a/trunk/net/x25/x25_dev.c +++ b/trunk/net/x25/x25_dev.c @@ -67,18 +67,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) return x25_rx_call_request(skb, nb, lci); /* - * Its not a Call Request, nor is it a control frame. - * Can we forward it? + * Its not a Call Request, nor is it a control frame. + * Let caller throw it away. */ - - if (x25_forward_data(lci, nb, skb)) { - if (frametype == X25_CLEAR_CONFIRMATION) { - x25_clear_forward_by_lci(lci); - } - kfree_skb(skb); - return 1; - } - /* x25_transmit_clear_request(nb, lci, 0x0D); */ diff --git a/trunk/net/x25/x25_forward.c b/trunk/net/x25/x25_forward.c deleted file mode 100644 index d339e0c810a8..000000000000 --- a/trunk/net/x25/x25_forward.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This module: - * This module 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. - * - * History - * 03-01-2007 Added forwarding for x.25 Andrew Hendry - */ -#include -#include -#include - -struct list_head x25_forward_list = LIST_HEAD_INIT(x25_forward_list); -DEFINE_RWLOCK(x25_forward_list_lock); - -int x25_forward_call(struct x25_address *dest_addr, struct x25_neigh *from, - struct sk_buff *skb, int lci) -{ - struct x25_route *rt; - struct x25_neigh *neigh_new = NULL; - struct list_head *entry; - struct x25_forward *x25_frwd, *new_frwd; - struct sk_buff *skbn; - short same_lci = 0; - int rc = 0; - - if ((rt = x25_get_route(dest_addr)) != NULL) { - - if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) { - /* This shouldnt happen, if it occurs somehow - * do something sensible - */ - goto out_put_route; - } - - /* Avoid a loop. This is the normal exit path for a - * system with only one x.25 iface and default route - */ - if (rt->dev == from->dev) { - goto out_put_nb; - } - - /* Remote end sending a call request on an already - * established LCI? It shouldnt happen, just in case.. - */ - read_lock_bh(&x25_forward_list_lock); - list_for_each(entry, &x25_forward_list) { - x25_frwd = list_entry(entry, struct x25_forward, node); - if (x25_frwd->lci == lci) { - printk(KERN_WARNING "X.25: call request for lci which is already registered!, transmitting but not registering new pair\n"); - same_lci = 1; - } - } - read_unlock_bh(&x25_forward_list_lock); - - /* Save the forwarding details for future traffic */ - if (!same_lci){ - if ((new_frwd = kmalloc(sizeof(struct x25_forward), - GFP_ATOMIC)) == NULL){ - rc = -ENOMEM; - goto out_put_nb; - } - new_frwd->lci = lci; - new_frwd->dev1 = rt->dev; - new_frwd->dev2 = from->dev; - write_lock_bh(&x25_forward_list_lock); - list_add(&new_frwd->node, &x25_forward_list); - write_unlock_bh(&x25_forward_list_lock); - } - - /* Forward the call request */ - if ( (skbn = skb_clone(skb, GFP_ATOMIC)) == NULL){ - goto out_put_nb; - } - x25_transmit_link(skbn, neigh_new); - rc = 1; - } - - -out_put_nb: - x25_neigh_put(neigh_new); - -out_put_route: - x25_route_put(rt); - return rc; -} - - -int x25_forward_data(int lci, struct x25_neigh *from, struct sk_buff *skb) { - - struct x25_forward *frwd; - struct list_head *entry; - struct net_device *peer = NULL; - struct x25_neigh *nb; - struct sk_buff *skbn; - int rc = 0; - - read_lock_bh(&x25_forward_list_lock); - list_for_each(entry, &x25_forward_list) { - frwd = list_entry(entry, struct x25_forward, node); - if (frwd->lci == lci) { - /* The call is established, either side can send */ - if (from->dev == frwd->dev1) { - peer = frwd->dev2; - } else { - peer = frwd->dev1; - } - break; - } - } - read_unlock_bh(&x25_forward_list_lock); - - if ( (nb = x25_get_neigh(peer)) == NULL) - goto out; - - if ( (skbn = pskb_copy(skb, GFP_ATOMIC)) == NULL){ - goto out; - - } - x25_transmit_link(skbn, nb); - - x25_neigh_put(nb); - rc = 1; -out: - return rc; -} - -void x25_clear_forward_by_lci(unsigned int lci) -{ - struct x25_forward *fwd; - struct list_head *entry, *tmp; - - write_lock_bh(&x25_forward_list_lock); - - list_for_each_safe(entry, tmp, &x25_forward_list) { - fwd = list_entry(entry, struct x25_forward, node); - if (fwd->lci == lci) { - list_del(&fwd->node); - kfree(fwd); - } - } - write_unlock_bh(&x25_forward_list_lock); -} - - -void x25_clear_forward_by_dev(struct net_device *dev) -{ - struct x25_forward *fwd; - struct list_head *entry, *tmp; - - write_lock_bh(&x25_forward_list_lock); - - list_for_each_safe(entry, tmp, &x25_forward_list) { - fwd = list_entry(entry, struct x25_forward, node); - if ((fwd->dev1 == dev) || (fwd->dev2 == dev)){ - list_del(&fwd->node); - kfree(fwd); - } - } - write_unlock_bh(&x25_forward_list_lock); -} diff --git a/trunk/net/x25/x25_proc.c b/trunk/net/x25/x25_proc.c index e0470bd8c2f9..a11837d361d2 100644 --- a/trunk/net/x25/x25_proc.c +++ b/trunk/net/x25/x25_proc.c @@ -165,75 +165,6 @@ static int x25_seq_socket_show(struct seq_file *seq, void *v) return 0; } -static __inline__ struct x25_forward *x25_get_forward_idx(loff_t pos) -{ - struct x25_forward *f; - struct list_head *entry; - - list_for_each(entry, &x25_forward_list) { - f = list_entry(entry, struct x25_forward, node); - if (!pos--) - goto found; - } - - f = NULL; -found: - return f; -} - -static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos) -{ - loff_t l = *pos; - - read_lock_bh(&x25_forward_list_lock); - return l ? x25_get_forward_idx(--l) : SEQ_START_TOKEN; -} - -static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct x25_forward *f; - - ++*pos; - if (v == SEQ_START_TOKEN) { - f = NULL; - if (!list_empty(&x25_forward_list)) - f = list_entry(x25_forward_list.next, - struct x25_forward, node); - goto out; - } - f = v; - if (f->node.next != &x25_forward_list) - f = list_entry(f->node.next, struct x25_forward, node); - else - f = NULL; -out: - return f; - -} - -static void x25_seq_forward_stop(struct seq_file *seq, void *v) -{ - read_unlock_bh(&x25_forward_list_lock); -} - -static int x25_seq_forward_show(struct seq_file *seq, void *v) -{ - struct x25_forward *f; - - if (v == SEQ_START_TOKEN) { - seq_printf(seq, "lci dev1 dev2\n"); - goto out; - } - - f = v; - - seq_printf(seq, "%d %-10s %-10s\n", - f->lci, f->dev1->name, f->dev2->name); - -out: - return 0; -} - static struct seq_operations x25_seq_route_ops = { .start = x25_seq_route_start, .next = x25_seq_route_next, @@ -248,13 +179,6 @@ static struct seq_operations x25_seq_socket_ops = { .show = x25_seq_socket_show, }; -static struct seq_operations x25_seq_forward_ops = { - .start = x25_seq_forward_start, - .next = x25_seq_forward_next, - .stop = x25_seq_forward_stop, - .show = x25_seq_forward_show, -}; - static int x25_seq_socket_open(struct inode *inode, struct file *file) { return seq_open(file, &x25_seq_socket_ops); @@ -265,11 +189,6 @@ static int x25_seq_route_open(struct inode *inode, struct file *file) return seq_open(file, &x25_seq_route_ops); } -static int x25_seq_forward_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &x25_seq_forward_ops); -} - static struct file_operations x25_seq_socket_fops = { .owner = THIS_MODULE, .open = x25_seq_socket_open, @@ -286,14 +205,6 @@ static struct file_operations x25_seq_route_fops = { .release = seq_release, }; -static struct file_operations x25_seq_forward_fops = { - .owner = THIS_MODULE, - .open = x25_seq_forward_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - static struct proc_dir_entry *x25_proc_dir; int __init x25_proc_init(void) @@ -314,17 +225,9 @@ int __init x25_proc_init(void) if (!p) goto out_socket; p->proc_fops = &x25_seq_socket_fops; - - p = create_proc_entry("forward", S_IRUGO, x25_proc_dir); - if (!p) - goto out_forward; - p->proc_fops = &x25_seq_forward_fops; rc = 0; - out: return rc; -out_forward: - remove_proc_entry("socket", x25_proc_dir); out_socket: remove_proc_entry("route", x25_proc_dir); out_route: @@ -334,7 +237,6 @@ int __init x25_proc_init(void) void __exit x25_proc_exit(void) { - remove_proc_entry("forward", x25_proc_dir); remove_proc_entry("route", x25_proc_dir); remove_proc_entry("socket", x25_proc_dir); remove_proc_entry("x25", proc_net); diff --git a/trunk/net/x25/x25_route.c b/trunk/net/x25/x25_route.c index 883a848bca5b..2a3fe986b245 100644 --- a/trunk/net/x25/x25_route.c +++ b/trunk/net/x25/x25_route.c @@ -119,9 +119,6 @@ void x25_route_device_down(struct net_device *dev) __x25_remove_route(rt); } write_unlock_bh(&x25_route_list_lock); - - /* Remove any related forwarding */ - x25_clear_forward_by_dev(dev); } /* diff --git a/trunk/net/xfrm/Kconfig b/trunk/net/xfrm/Kconfig index 577a4f821b98..0faab6332586 100644 --- a/trunk/net/xfrm/Kconfig +++ b/trunk/net/xfrm/Kconfig @@ -24,17 +24,6 @@ config XFRM_SUB_POLICY If unsure, say N. -config XFRM_MIGRATE - bool "Transformation migrate database (EXPERIMENTAL)" - depends on XFRM && EXPERIMENTAL - ---help--- - A feature to update locator(s) of a given IPsec security - association dynamically. This feature is required, for - instance, in a Mobile IPv6 environment with IPsec configuration - where mobile nodes change their attachment point to the Internet. - - If unsure, say N. - config NET_KEY tristate "PF_KEY sockets" select XFRM @@ -45,19 +34,4 @@ config NET_KEY Say Y unless you know what you are doing. -config NET_KEY_MIGRATE - bool "PF_KEY MIGRATE (EXPERIMENTAL)" - depends on NET_KEY && EXPERIMENTAL - select XFRM_MIGRATE - ---help--- - Add a PF_KEY MIGRATE message to PF_KEYv2 socket family. - The PF_KEY MIGRATE message is used to dynamically update - locator(s) of a given IPsec security association. - This feature is required, for instance, in a Mobile IPv6 - environment with IPsec configuration where mobile nodes - change their attachment point to the Internet. Detail - information can be found in the internet-draft - . - - If unsure, say N. diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index 248f94814dfb..f1cf3402e75c 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -265,23 +265,6 @@ static struct xfrm_algo_desc ealg_list[] = { .sadb_alg_maxbits = 256, } }, -{ - .name = "cbc(camellia)", - - .uinfo = { - .encr = { - .blockbits = 128, - .defkeybits = 128, - } - }, - - .desc = { - .sadb_alg_id = SADB_X_EALG_CAMELLIACBC, - .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 128, - .sadb_alg_maxbits = 256 - } -}, { .name = "cbc(twofish)", .compat = "twofish", diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index fa7ce060b454..b7e537fe2d75 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -2236,234 +2236,3 @@ void __init xfrm_init(void) xfrm_input_init(); } -#ifdef CONFIG_XFRM_MIGRATE -static int xfrm_migrate_selector_match(struct xfrm_selector *sel_cmp, - struct xfrm_selector *sel_tgt) -{ - if (sel_cmp->proto == IPSEC_ULPROTO_ANY) { - if (sel_tgt->family == sel_cmp->family && - xfrm_addr_cmp(&sel_tgt->daddr, &sel_cmp->daddr, - sel_cmp->family) == 0 && - xfrm_addr_cmp(&sel_tgt->saddr, &sel_cmp->saddr, - sel_cmp->family) == 0 && - sel_tgt->prefixlen_d == sel_cmp->prefixlen_d && - sel_tgt->prefixlen_s == sel_cmp->prefixlen_s) { - return 1; - } - } else { - if (memcmp(sel_tgt, sel_cmp, sizeof(*sel_tgt)) == 0) { - return 1; - } - } - return 0; -} - -static struct xfrm_policy * xfrm_migrate_policy_find(struct xfrm_selector *sel, - u8 dir, u8 type) -{ - struct xfrm_policy *pol, *ret = NULL; - struct hlist_node *entry; - struct hlist_head *chain; - u32 priority = ~0U; - - read_lock_bh(&xfrm_policy_lock); - chain = policy_hash_direct(&sel->daddr, &sel->saddr, sel->family, dir); - hlist_for_each_entry(pol, entry, chain, bydst) { - if (xfrm_migrate_selector_match(sel, &pol->selector) && - pol->type == type) { - ret = pol; - priority = ret->priority; - break; - } - } - chain = &xfrm_policy_inexact[dir]; - hlist_for_each_entry(pol, entry, chain, bydst) { - if (xfrm_migrate_selector_match(sel, &pol->selector) && - pol->type == type && - pol->priority < priority) { - ret = pol; - break; - } - } - - if (ret) - xfrm_pol_hold(ret); - - read_unlock_bh(&xfrm_policy_lock); - - return ret; -} - -static int migrate_tmpl_match(struct xfrm_migrate *m, struct xfrm_tmpl *t) -{ - int match = 0; - - if (t->mode == m->mode && t->id.proto == m->proto && - (m->reqid == 0 || t->reqid == m->reqid)) { - switch (t->mode) { - case XFRM_MODE_TUNNEL: - case XFRM_MODE_BEET: - if (xfrm_addr_cmp(&t->id.daddr, &m->old_daddr, - m->old_family) == 0 && - xfrm_addr_cmp(&t->saddr, &m->old_saddr, - m->old_family) == 0) { - match = 1; - } - break; - case XFRM_MODE_TRANSPORT: - /* in case of transport mode, template does not store - any IP addresses, hence we just compare mode and - protocol */ - match = 1; - break; - default: - break; - } - } - return match; -} - -/* update endpoint address(es) of template(s) */ -static int xfrm_policy_migrate(struct xfrm_policy *pol, - struct xfrm_migrate *m, int num_migrate) -{ - struct xfrm_migrate *mp; - struct dst_entry *dst; - int i, j, n = 0; - - write_lock_bh(&pol->lock); - if (unlikely(pol->dead)) { - /* target policy has been deleted */ - write_unlock_bh(&pol->lock); - return -ENOENT; - } - - for (i = 0; i < pol->xfrm_nr; i++) { - for (j = 0, mp = m; j < num_migrate; j++, mp++) { - if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i])) - continue; - n++; - if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL) - continue; - /* update endpoints */ - memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr, - sizeof(pol->xfrm_vec[i].id.daddr)); - memcpy(&pol->xfrm_vec[i].saddr, &mp->new_saddr, - sizeof(pol->xfrm_vec[i].saddr)); - pol->xfrm_vec[i].encap_family = mp->new_family; - /* flush bundles */ - while ((dst = pol->bundles) != NULL) { - pol->bundles = dst->next; - dst_free(dst); - } - } - } - - write_unlock_bh(&pol->lock); - - if (!n) - return -ENODATA; - - return 0; -} - -static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate) -{ - int i, j; - - if (num_migrate < 1 || num_migrate > XFRM_MAX_DEPTH) - return -EINVAL; - - for (i = 0; i < num_migrate; i++) { - if ((xfrm_addr_cmp(&m[i].old_daddr, &m[i].new_daddr, - m[i].old_family) == 0) && - (xfrm_addr_cmp(&m[i].old_saddr, &m[i].new_saddr, - m[i].old_family) == 0)) - return -EINVAL; - if (xfrm_addr_any(&m[i].new_daddr, m[i].new_family) || - xfrm_addr_any(&m[i].new_saddr, m[i].new_family)) - return -EINVAL; - - /* check if there is any duplicated entry */ - for (j = i + 1; j < num_migrate; j++) { - if (!memcmp(&m[i].old_daddr, &m[j].old_daddr, - sizeof(m[i].old_daddr)) && - !memcmp(&m[i].old_saddr, &m[j].old_saddr, - sizeof(m[i].old_saddr)) && - m[i].proto == m[j].proto && - m[i].mode == m[j].mode && - m[i].reqid == m[j].reqid && - m[i].old_family == m[j].old_family) - return -EINVAL; - } - } - - return 0; -} - -int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_migrate) -{ - int i, err, nx_cur = 0, nx_new = 0; - struct xfrm_policy *pol = NULL; - struct xfrm_state *x, *xc; - struct xfrm_state *x_cur[XFRM_MAX_DEPTH]; - struct xfrm_state *x_new[XFRM_MAX_DEPTH]; - struct xfrm_migrate *mp; - - if ((err = xfrm_migrate_check(m, num_migrate)) < 0) - goto out; - - /* Stage 1 - find policy */ - if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) { - err = -ENOENT; - goto out; - } - - /* Stage 2 - find and update state(s) */ - for (i = 0, mp = m; i < num_migrate; i++, mp++) { - if ((x = xfrm_migrate_state_find(mp))) { - x_cur[nx_cur] = x; - nx_cur++; - if ((xc = xfrm_state_migrate(x, mp))) { - x_new[nx_new] = xc; - nx_new++; - } else { - err = -ENODATA; - goto restore_state; - } - } - } - - /* Stage 3 - update policy */ - if ((err = xfrm_policy_migrate(pol, m, num_migrate)) < 0) - goto restore_state; - - /* Stage 4 - delete old state(s) */ - if (nx_cur) { - xfrm_states_put(x_cur, nx_cur); - xfrm_states_delete(x_cur, nx_cur); - } - - /* Stage 5 - announce */ - km_migrate(sel, dir, type, m, num_migrate); - - xfrm_pol_put(pol); - - return 0; -out: - return err; - -restore_state: - if (pol) - xfrm_pol_put(pol); - if (nx_cur) - xfrm_states_put(x_cur, nx_cur); - if (nx_new) - xfrm_states_delete(x_new, nx_new); - - return err; -} -EXPORT_SYMBOL(xfrm_migrate); -#endif - diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 91b02687db52..fdb08d9f34aa 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -183,6 +183,9 @@ static DEFINE_SPINLOCK(xfrm_state_gc_lock); int __xfrm_state_delete(struct xfrm_state *x); +static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); +static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); + int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); void km_state_expired(struct xfrm_state *x, int hard, u32 pid); @@ -828,160 +831,6 @@ int xfrm_state_add(struct xfrm_state *x) } EXPORT_SYMBOL(xfrm_state_add); -#ifdef CONFIG_XFRM_MIGRATE -struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) -{ - int err = -ENOMEM; - struct xfrm_state *x = xfrm_state_alloc(); - if (!x) - goto error; - - memcpy(&x->id, &orig->id, sizeof(x->id)); - memcpy(&x->sel, &orig->sel, sizeof(x->sel)); - memcpy(&x->lft, &orig->lft, sizeof(x->lft)); - x->props.mode = orig->props.mode; - x->props.replay_window = orig->props.replay_window; - x->props.reqid = orig->props.reqid; - x->props.family = orig->props.family; - x->props.saddr = orig->props.saddr; - - if (orig->aalg) { - x->aalg = xfrm_algo_clone(orig->aalg); - if (!x->aalg) - goto error; - } - x->props.aalgo = orig->props.aalgo; - - if (orig->ealg) { - x->ealg = xfrm_algo_clone(orig->ealg); - if (!x->ealg) - goto error; - } - x->props.ealgo = orig->props.ealgo; - - if (orig->calg) { - x->calg = xfrm_algo_clone(orig->calg); - if (!x->calg) - goto error; - } - x->props.calgo = orig->props.calgo; - - if (orig->encap) { - x->encap = kmemdup(orig->encap, sizeof(*x->encap), GFP_KERNEL); - if (!x->encap) - goto error; - } - - if (orig->coaddr) { - x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr), - GFP_KERNEL); - if (!x->coaddr) - goto error; - } - - err = xfrm_init_state(x); - if (err) - goto error; - - x->props.flags = orig->props.flags; - - x->curlft.add_time = orig->curlft.add_time; - x->km.state = orig->km.state; - x->km.seq = orig->km.seq; - - return x; - - error: - if (errp) - *errp = err; - if (x) { - kfree(x->aalg); - kfree(x->ealg); - kfree(x->calg); - kfree(x->encap); - kfree(x->coaddr); - } - kfree(x); - return NULL; -} -EXPORT_SYMBOL(xfrm_state_clone); - -/* xfrm_state_lock is held */ -struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m) -{ - unsigned int h; - struct xfrm_state *x; - struct hlist_node *entry; - - if (m->reqid) { - h = xfrm_dst_hash(&m->old_daddr, &m->old_saddr, - m->reqid, m->old_family); - hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) { - if (x->props.mode != m->mode || - x->id.proto != m->proto) - continue; - if (m->reqid && x->props.reqid != m->reqid) - continue; - if (xfrm_addr_cmp(&x->id.daddr, &m->old_daddr, - m->old_family) || - xfrm_addr_cmp(&x->props.saddr, &m->old_saddr, - m->old_family)) - continue; - xfrm_state_hold(x); - return x; - } - } else { - h = xfrm_src_hash(&m->old_daddr, &m->old_saddr, - m->old_family); - hlist_for_each_entry(x, entry, xfrm_state_bysrc+h, bysrc) { - if (x->props.mode != m->mode || - x->id.proto != m->proto) - continue; - if (xfrm_addr_cmp(&x->id.daddr, &m->old_daddr, - m->old_family) || - xfrm_addr_cmp(&x->props.saddr, &m->old_saddr, - m->old_family)) - continue; - xfrm_state_hold(x); - return x; - } - } - - return NULL; -} -EXPORT_SYMBOL(xfrm_migrate_state_find); - -struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, - struct xfrm_migrate *m) -{ - struct xfrm_state *xc; - int err; - - xc = xfrm_state_clone(x, &err); - if (!xc) - return NULL; - - memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr)); - memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr)); - - /* add state */ - if (!xfrm_addr_cmp(&x->id.daddr, &m->new_daddr, m->new_family)) { - /* a care is needed when the destination address of the - state is to be updated as it is a part of triplet */ - xfrm_state_insert(xc); - } else { - if ((err = xfrm_state_add(xc)) < 0) - goto error; - } - - return xc; -error: - kfree(xc); - return NULL; -} -EXPORT_SYMBOL(xfrm_state_migrate); -#endif - int xfrm_state_update(struct xfrm_state *x) { struct xfrm_state *x1; @@ -1496,26 +1345,6 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) } EXPORT_SYMBOL(km_policy_expired); -int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_migrate) -{ - int err = -EINVAL; - int ret; - struct xfrm_mgr *km; - - read_lock(&xfrm_km_lock); - list_for_each_entry(km, &xfrm_km_list, list) { - if (km->migrate) { - ret = km->migrate(sel, dir, type, m, num_migrate); - if (!ret) - err = ret; - } - } - read_unlock(&xfrm_km_lock); - return err; -} -EXPORT_SYMBOL(km_migrate); - int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr) { int err = -EINVAL; @@ -1629,7 +1458,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) } EXPORT_SYMBOL(xfrm_state_unregister_afinfo); -struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) +static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) { struct xfrm_state_afinfo *afinfo; if (unlikely(family >= NPROTO)) @@ -1641,14 +1470,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) return afinfo; } -void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) +static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) { read_unlock(&xfrm_state_afinfo_lock); } -EXPORT_SYMBOL(xfrm_state_get_afinfo); -EXPORT_SYMBOL(xfrm_state_put_afinfo); - /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ void xfrm_state_delete_tunnel(struct xfrm_state *x) { diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index 079a5d315759..82f36d396fca 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -1632,176 +1632,6 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, return 0; } -#ifdef CONFIG_XFRM_MIGRATE -static int verify_user_migrate(struct rtattr **xfrma) -{ - struct rtattr *rt = xfrma[XFRMA_MIGRATE-1]; - struct xfrm_user_migrate *um; - - if (!rt) - return -EINVAL; - - if ((rt->rta_len - sizeof(*rt)) < sizeof(*um)) - return -EINVAL; - - return 0; -} - -static int copy_from_user_migrate(struct xfrm_migrate *ma, - struct rtattr **xfrma, int *num) -{ - struct rtattr *rt = xfrma[XFRMA_MIGRATE-1]; - struct xfrm_user_migrate *um; - int i, num_migrate; - - um = RTA_DATA(rt); - num_migrate = (rt->rta_len - sizeof(*rt)) / sizeof(*um); - - if (num_migrate <= 0 || num_migrate > XFRM_MAX_DEPTH) - return -EINVAL; - - for (i = 0; i < num_migrate; i++, um++, ma++) { - memcpy(&ma->old_daddr, &um->old_daddr, sizeof(ma->old_daddr)); - memcpy(&ma->old_saddr, &um->old_saddr, sizeof(ma->old_saddr)); - memcpy(&ma->new_daddr, &um->new_daddr, sizeof(ma->new_daddr)); - memcpy(&ma->new_saddr, &um->new_saddr, sizeof(ma->new_saddr)); - - ma->proto = um->proto; - ma->mode = um->mode; - ma->reqid = um->reqid; - - ma->old_family = um->old_family; - ma->new_family = um->new_family; - } - - *num = i; - return 0; -} - -static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, - struct rtattr **xfrma) -{ - struct xfrm_userpolicy_id *pi = NLMSG_DATA(nlh); - struct xfrm_migrate m[XFRM_MAX_DEPTH]; - u8 type; - int err; - int n = 0; - - err = verify_user_migrate((struct rtattr **)xfrma); - if (err) - return err; - - err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); - if (err) - return err; - - err = copy_from_user_migrate((struct xfrm_migrate *)m, - (struct rtattr **)xfrma, &n); - if (err) - return err; - - if (!n) - return 0; - - xfrm_migrate(&pi->sel, pi->dir, type, m, n); - - return 0; -} -#else -static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, - struct rtattr **xfrma) -{ - return -ENOPROTOOPT; -} -#endif - -#ifdef CONFIG_XFRM_MIGRATE -static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb) -{ - struct xfrm_user_migrate um; - - memset(&um, 0, sizeof(um)); - um.proto = m->proto; - um.mode = m->mode; - um.reqid = m->reqid; - um.old_family = m->old_family; - memcpy(&um.old_daddr, &m->old_daddr, sizeof(um.old_daddr)); - memcpy(&um.old_saddr, &m->old_saddr, sizeof(um.old_saddr)); - um.new_family = m->new_family; - memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr)); - memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr)); - - RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um); - return 0; - -rtattr_failure: - return -1; -} - -static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, - int num_migrate, struct xfrm_selector *sel, - u8 dir, u8 type) -{ - struct xfrm_migrate *mp; - struct xfrm_userpolicy_id *pol_id; - struct nlmsghdr *nlh; - unsigned char *b = skb->tail; - int i; - - nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id)); - pol_id = NLMSG_DATA(nlh); - nlh->nlmsg_flags = 0; - - /* copy data from selector, dir, and type to the pol_id */ - memset(pol_id, 0, sizeof(*pol_id)); - memcpy(&pol_id->sel, sel, sizeof(pol_id->sel)); - pol_id->dir = dir; - - if (copy_to_user_policy_type(type, skb) < 0) - goto nlmsg_failure; - - for (i = 0, mp = m ; i < num_migrate; i++, mp++) { - if (copy_to_user_migrate(mp, skb) < 0) - goto nlmsg_failure; - } - - nlh->nlmsg_len = skb->tail - b; - return skb->len; -nlmsg_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_migrate) -{ - struct sk_buff *skb; - size_t len; - - len = RTA_SPACE(sizeof(struct xfrm_user_migrate) * num_migrate); - len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_id)); -#ifdef CONFIG_XFRM_SUB_POLICY - len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); -#endif - skb = alloc_skb(len, GFP_ATOMIC); - if (skb == NULL) - return -ENOMEM; - - /* build migrate */ - if (build_migrate(skb, m, num_migrate, sel, dir, type) < 0) - BUG(); - - NETLINK_CB(skb).dst_group = XFRMNLGRP_MIGRATE; - return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, - GFP_ATOMIC); -} -#else -static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, - struct xfrm_migrate *m, int num_migrate) -{ - return -ENOPROTOOPT; -} -#endif #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) @@ -1823,7 +1653,6 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), - [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), }; #undef XMSGSIZE @@ -1850,7 +1679,6 @@ static struct xfrm_link { [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = { .doit = xfrm_new_ae }, [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, - [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, }; static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) @@ -2457,7 +2285,6 @@ static struct xfrm_mgr netlink_mgr = { .compile_policy = xfrm_compile_policy, .notify_policy = xfrm_send_policy_notify, .report = xfrm_send_report, - .migrate = xfrm_send_migrate, }; static int __init xfrm_user_init(void) diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index 97532bbc2ccb..9d77300746c6 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -76,8 +76,6 @@ source "sound/sparc/Kconfig" source "sound/parisc/Kconfig" -source "sound/soc/Kconfig" - endmenu menu "Open Sound System" diff --git a/trunk/sound/Makefile b/trunk/sound/Makefile index b7c7fb7c24c8..9aee54c4882d 100644 --- a/trunk/sound/Makefile +++ b/trunk/sound/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_DMASOUND) += oss/ -obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ +obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ obj-$(CONFIG_SND_AOA) += aoa/ # This one must be compilable even if sound is configured out diff --git a/trunk/sound/ac97_bus.c b/trunk/sound/ac97_bus.c index 7fa37e15f196..66de2c2f1554 100644 --- a/trunk/sound/ac97_bus.c +++ b/trunk/sound/ac97_bus.c @@ -26,7 +26,6 @@ static int ac97_bus_match(struct device *dev, struct device_driver *drv) return 1; } -#ifdef CONFIG_PM static int ac97_bus_suspend(struct device *dev, pm_message_t state) { int ret = 0; @@ -46,15 +45,12 @@ static int ac97_bus_resume(struct device *dev) return ret; } -#endif /* CONFIG_PM */ struct bus_type ac97_bus_type = { .name = "ac97", .match = ac97_bus_match, -#ifdef CONFIG_PM .suspend = ac97_bus_suspend, .resume = ac97_bus_resume, -#endif /* CONFIG_PM */ }; static int __init ac97_bus_init(void) diff --git a/trunk/sound/aoa/aoa.h b/trunk/sound/aoa/aoa.h index 541b908f3cdf..378ef1e9879b 100644 --- a/trunk/sound/aoa/aoa.h +++ b/trunk/sound/aoa/aoa.h @@ -99,7 +99,7 @@ struct aoa_fabric { * that are not assigned yet are passed to the fabric * again for reconsideration. */ extern int -aoa_fabric_register(struct aoa_fabric *fabric, struct device *dev); +aoa_fabric_register(struct aoa_fabric *fabric); /* it is vital to call this when the fabric exits! * When calling, the remove_codec will be called diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c index b00fc4842c93..0b7650788f1f 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -825,16 +825,7 @@ static int onyx_resume(struct codec_info_item *cii) int err = -ENXIO; mutex_lock(&onyx->mutex); - - /* reset codec */ - onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); - msleep(1); - onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 1); - msleep(1); - onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); - msleep(1); - - /* take codec out of suspend (if it still is after reset) */ + /* take codec out of suspend */ if (onyx_read_register(onyx, ONYX_REG_CONTROL, &v)) goto out_unlock; onyx_write_register(onyx, ONYX_REG_CONTROL, v & ~(ONYX_ADPSV | ONYX_DAPSV)); diff --git a/trunk/sound/aoa/core/snd-aoa-alsa.c b/trunk/sound/aoa/core/snd-aoa-alsa.c index 17fe689ed287..b42fdea77ed0 100644 --- a/trunk/sound/aoa/core/snd-aoa-alsa.c +++ b/trunk/sound/aoa/core/snd-aoa-alsa.c @@ -14,7 +14,7 @@ MODULE_PARM_DESC(index, "index for AOA sound card."); static struct aoa_card *aoa_card; -int aoa_alsa_init(char *name, struct module *mod, struct device *dev) +int aoa_alsa_init(char *name, struct module *mod) { struct snd_card *alsa_card; int err; @@ -28,7 +28,6 @@ int aoa_alsa_init(char *name, struct module *mod, struct device *dev) return -ENOMEM; aoa_card = alsa_card->private_data; aoa_card->alsa_card = alsa_card; - alsa_card->dev = dev; strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver)); strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname)); strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname)); @@ -60,7 +59,7 @@ void aoa_alsa_cleanup(void) } int aoa_snd_device_new(snd_device_type_t type, - void * device_data, struct snd_device_ops * ops) + void * device_data, struct snd_device_ops * ops) { struct snd_card *card = aoa_get_card(); int err; diff --git a/trunk/sound/aoa/core/snd-aoa-alsa.h b/trunk/sound/aoa/core/snd-aoa-alsa.h index 9669e4489cab..660d2f1793bb 100644 --- a/trunk/sound/aoa/core/snd-aoa-alsa.h +++ b/trunk/sound/aoa/core/snd-aoa-alsa.h @@ -10,7 +10,7 @@ #define __SND_AOA_ALSA_H #include "../aoa.h" -extern int aoa_alsa_init(char *name, struct module *mod, struct device *dev); +extern int aoa_alsa_init(char *name, struct module *mod); extern void aoa_alsa_cleanup(void); #endif /* __SND_AOA_ALSA_H */ diff --git a/trunk/sound/aoa/core/snd-aoa-core.c b/trunk/sound/aoa/core/snd-aoa-core.c index 19fdae400687..ecd2d8263f2d 100644 --- a/trunk/sound/aoa/core/snd-aoa-core.c +++ b/trunk/sound/aoa/core/snd-aoa-core.c @@ -82,7 +82,7 @@ void aoa_codec_unregister(struct aoa_codec *codec) } EXPORT_SYMBOL_GPL(aoa_codec_unregister); -int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev) +int aoa_fabric_register(struct aoa_fabric *new_fabric) { struct aoa_codec *c; int err; @@ -98,7 +98,7 @@ int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev) if (!new_fabric) return -EINVAL; - err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev); + err = aoa_alsa_init(new_fabric->name, new_fabric->owner); if (err) return err; diff --git a/trunk/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/trunk/sound/aoa/fabrics/snd-aoa-fabric-layout.c index 1b94ba6dd279..172eb95476c0 100644 --- a/trunk/sound/aoa/fabrics/snd-aoa-fabric-layout.c +++ b/trunk/sound/aoa/fabrics/snd-aoa-fabric-layout.c @@ -1014,7 +1014,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) ldev->gpio.methods->init(&ldev->gpio); - err = aoa_fabric_register(&layout_fabric, &sdev->ofdev.dev); + err = aoa_fabric_register(&layout_fabric); if (err && err != -EALREADY) { printk(KERN_INFO "snd-aoa-fabric-layout: can't use," " another fabric is active!\n"); @@ -1034,9 +1034,9 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) list_del(&ldev->list); layouts_list_items--; outnodev: - of_node_put(sound); + if (sound) of_node_put(sound); layout_device = NULL; - kfree(ldev); + if (ldev) kfree(ldev); return -ENODEV; } @@ -1077,6 +1077,8 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta { struct layout_dev *ldev = sdev->ofdev.dev.driver_data; + printk("aoa_fabric_layout_suspend()\n"); + if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_off(&ldev->gpio); @@ -1087,6 +1089,8 @@ static int aoa_fabric_layout_resume(struct soundbus_dev *sdev) { struct layout_dev *ldev = sdev->ofdev.dev.driver_data; + printk("aoa_fabric_layout_resume()\n"); + if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_restore(&ldev->gpio); @@ -1103,9 +1107,6 @@ static struct soundbus_driver aoa_soundbus_driver = { .suspend = aoa_fabric_layout_suspend, .resume = aoa_fabric_layout_resume, #endif - .driver = { - .owner = THIS_MODULE, - } }; static int __init aoa_fabric_layout_init(void) diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c index e36f6aa448d4..e593a1333fe3 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c @@ -41,8 +41,8 @@ static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, struct dbdma_command_mem *r, int numcmds) { - /* one more for rounding, one for branch back, one for stop command */ - r->size = (numcmds + 3) * sizeof(struct dbdma_cmd); + /* one more for rounding */ + r->size = (numcmds+1) * sizeof(struct dbdma_cmd); /* We use the PCI APIs for now until the generic one gets fixed * enough or until we get some macio-specific versions */ @@ -377,8 +377,11 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) if (i2sdev->sound.pcm) { /* Suspend PCM streams */ snd_pcm_suspend_all(i2sdev->sound.pcm); + /* Probably useless as we handle + * power transitions ourselves */ + snd_power_change_state(i2sdev->sound.pcm->card, + SNDRV_CTL_POWER_D3hot); } - /* Notify codecs */ list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { err = 0; @@ -387,11 +390,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) if (err) ret = err; } - - /* wait until streams are stopped */ - i2sbus_wait_for_stop_both(i2sdev); } - return ret; } @@ -403,9 +402,6 @@ static int i2sbus_resume(struct macio_dev* dev) int err, ret = 0; list_for_each_entry(i2sdev, &control->list, item) { - /* reset i2s bus format etc. */ - i2sbus_pcm_prepare_both(i2sdev); - /* Notify codecs so they can re-initialize */ list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { err = 0; @@ -414,6 +410,12 @@ static int i2sbus_resume(struct macio_dev* dev) if (err) ret = err; } + /* Notify Alsa */ + if (i2sdev->sound.pcm) { + /* Same comment as above, probably useless */ + snd_power_change_state(i2sdev->sound.pcm->card, + SNDRV_CTL_POWER_D0); + } } return ret; diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c index c6b42f9bdbc9..5eff30b10201 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c @@ -125,8 +125,7 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in) } /* bus dependent stuff */ hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_JOINT_DUPLEX; + SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME; CHECK_RATE(5512); CHECK_RATE(8000); @@ -246,78 +245,18 @@ static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in) return err; } -static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev, - struct pcm_info *pi) -{ - unsigned long flags; - struct completion done; - long timeout; - - spin_lock_irqsave(&i2sdev->low_lock, flags); - if (pi->dbdma_ring.stopping) { - init_completion(&done); - pi->stop_completion = &done; - spin_unlock_irqrestore(&i2sdev->low_lock, flags); - timeout = wait_for_completion_timeout(&done, HZ); - spin_lock_irqsave(&i2sdev->low_lock, flags); - pi->stop_completion = NULL; - if (timeout == 0) { - /* timeout expired, stop dbdma forcefully */ - printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n"); - /* make sure RUN, PAUSE and S0 bits are cleared */ - out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16); - pi->dbdma_ring.stopping = 0; - timeout = 10; - while (in_le32(&pi->dbdma->status) & ACTIVE) { - if (--timeout <= 0) - break; - udelay(1); - } - } - } - spin_unlock_irqrestore(&i2sdev->low_lock, flags); -} - -#ifdef CONFIG_PM -void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev) -{ - struct pcm_info *pi; - - get_pcm_info(i2sdev, 0, &pi, NULL); - i2sbus_wait_for_stop(i2sdev, pi); - get_pcm_info(i2sdev, 1, &pi, NULL); - i2sbus_wait_for_stop(i2sdev, pi); -} -#endif - static int i2sbus_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); } -static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in) +static int i2sbus_hw_free(struct snd_pcm_substream *substream) { - struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream); - struct pcm_info *pi; - - get_pcm_info(i2sdev, in, &pi, NULL); - if (pi->dbdma_ring.stopping) - i2sbus_wait_for_stop(i2sdev, pi); snd_pcm_lib_free_pages(substream); return 0; } -static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream) -{ - return i2sbus_hw_free(substream, 0); -} - -static int i2sbus_record_hw_free(struct snd_pcm_substream *substream) -{ - return i2sbus_hw_free(substream, 1); -} - static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) { /* whee. Hard work now. The user has selected a bitrate @@ -325,7 +264,7 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) * I2S controller appropriately. */ struct snd_pcm_runtime *runtime; struct dbdma_cmd *command; - int i, periodsize, nperiods; + int i, periodsize; dma_addr_t offset; struct bus_info bi; struct codec_info_item *cii; @@ -335,7 +274,6 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) struct pcm_info *pi, *other; int cnt; int result = 0; - unsigned int cmd, stopaddr; mutex_lock(&i2sdev->lock); @@ -345,13 +283,6 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) result = -EBUSY; goto out_unlock; } - if (pi->dbdma_ring.stopping) - i2sbus_wait_for_stop(i2sdev, pi); - - if (!pi->substream || !pi->substream->runtime) { - result = -EINVAL; - goto out_unlock; - } runtime = pi->substream->runtime; pi->active = 1; @@ -366,43 +297,24 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) i2sdev->rate = runtime->rate; periodsize = snd_pcm_lib_period_bytes(pi->substream); - nperiods = pi->substream->runtime->periods; pi->current_period = 0; /* generate dbdma command ring first */ command = pi->dbdma_ring.cmds; - memset(command, 0, (nperiods + 2) * sizeof(struct dbdma_cmd)); - - /* commands to DMA to/from the ring */ - /* - * For input, we need to do a graceful stop; if we abort - * the DMA, we end up with leftover bytes that corrupt - * the next recording. To do this we set the S0 status - * bit and wait for the DMA controller to stop. Each - * command has a branch condition to - * make it branch to a stop command if S0 is set. - * On input we also need to wait for the S7 bit to be - * set before turning off the DMA controller. - * In fact we do the graceful stop for output as well. - */ offset = runtime->dma_addr; - cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET | INTR_ALWAYS; - stopaddr = pi->dbdma_ring.bus_cmd_start + - (nperiods + 1) * sizeof(struct dbdma_cmd); - for (i = 0; i < nperiods; i++, command++, offset += periodsize) { - command->command = cpu_to_le16(cmd); - command->cmd_dep = cpu_to_le32(stopaddr); + for (i = 0; i < pi->substream->runtime->periods; + i++, command++, offset += periodsize) { + memset(command, 0, sizeof(struct dbdma_cmd)); + command->command = + cpu_to_le16((in ? INPUT_MORE : OUTPUT_MORE) | INTR_ALWAYS); command->phy_addr = cpu_to_le32(offset); command->req_count = cpu_to_le16(periodsize); + command->xfer_status = cpu_to_le16(0); } - - /* branch back to beginning of ring */ - command->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS); + /* last one branches back to first */ + command--; + command->command |= cpu_to_le16(BR_ALWAYS); command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start); - command++; - - /* set stop command */ - command->command = cpu_to_le16(DBDMA_STOP); /* ok, let's set the serial format and stuff */ switch (runtime->format) { @@ -523,18 +435,16 @@ static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in) return result; } -#ifdef CONFIG_PM -void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev) -{ - i2sbus_pcm_prepare(i2sdev, 0); - i2sbus_pcm_prepare(i2sdev, 1); -} -#endif +static struct dbdma_cmd STOP_CMD = { + .command = __constant_cpu_to_le16(DBDMA_STOP), +}; static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd) { struct codec_info_item *cii; struct pcm_info *pi; + int timeout; + struct dbdma_cmd tmp; int result = 0; unsigned long flags; @@ -554,50 +464,92 @@ static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd) cii->codec->start(cii, pi->substream); pi->dbdma_ring.running = 1; - if (pi->dbdma_ring.stopping) { - /* Clear the S0 bit, then see if we stopped yet */ - out_le32(&pi->dbdma->control, 1 << 16); - if (in_le32(&pi->dbdma->status) & ACTIVE) { - /* possible race here? */ - udelay(10); - if (in_le32(&pi->dbdma->status) & ACTIVE) { - pi->dbdma_ring.stopping = 0; - goto out_unlock; /* keep running */ - } - } + /* reset dma engine */ + out_le32(&pi->dbdma->control, + 0 | (RUN | PAUSE | FLUSH | WAKE) << 16); + timeout = 100; + while (in_le32(&pi->dbdma->status) & RUN && timeout--) + udelay(1); + if (timeout <= 0) { + printk(KERN_ERR + "i2sbus: error waiting for dma reset\n"); + result = -ENXIO; + goto out_unlock; } - /* make sure RUN, PAUSE and S0 bits are cleared */ - out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16); - - /* set branch condition select register */ - out_le32(&pi->dbdma->br_sel, (1 << 16) | 1); - /* write dma command buffer address to the dbdma chip */ out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start); + /* post PCI write */ + mb(); + (void)in_le32(&pi->dbdma->status); + + /* change first command to STOP */ + tmp = *pi->dbdma_ring.cmds; + *pi->dbdma_ring.cmds = STOP_CMD; + + /* set running state, remember that the first command is STOP */ + out_le32(&pi->dbdma->control, RUN | (RUN << 16)); + timeout = 100; + /* wait for STOP to be executed */ + while (in_le32(&pi->dbdma->status) & ACTIVE && timeout--) + udelay(1); + if (timeout <= 0) { + printk(KERN_ERR "i2sbus: error waiting for dma stop\n"); + result = -ENXIO; + goto out_unlock; + } + /* again, write dma command buffer address to the dbdma chip, + * this time of the first real command */ + *pi->dbdma_ring.cmds = tmp; + out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start); + /* post write */ + mb(); + (void)in_le32(&pi->dbdma->status); + + /* reset dma engine again */ + out_le32(&pi->dbdma->control, + 0 | (RUN | PAUSE | FLUSH | WAKE) << 16); + timeout = 100; + while (in_le32(&pi->dbdma->status) & RUN && timeout--) + udelay(1); + if (timeout <= 0) { + printk(KERN_ERR + "i2sbus: error waiting for dma reset\n"); + result = -ENXIO; + goto out_unlock; + } - /* initialize the frame count and current period */ - pi->current_period = 0; + /* wake up the chip with the next descriptor */ + out_le32(&pi->dbdma->control, + (RUN | WAKE) | ((RUN | WAKE) << 16)); + /* get the frame count */ pi->frame_count = in_le32(&i2sdev->intfregs->frame_count); - /* set the DMA controller running */ - out_le32(&pi->dbdma->control, (RUN << 16) | RUN); - /* off you go! */ break; - case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: if (!pi->dbdma_ring.running) { result = -EALREADY; goto out_unlock; } - pi->dbdma_ring.running = 0; - /* Set the S0 bit to make the DMA branch to the stop cmd */ - out_le32(&pi->dbdma->control, (1 << 16) | 1); - pi->dbdma_ring.stopping = 1; + /* turn off all relevant bits */ + out_le32(&pi->dbdma->control, + (RUN | WAKE | FLUSH | PAUSE) << 16); + { + /* FIXME: move to own function */ + int timeout = 5000; + while ((in_le32(&pi->dbdma->status) & RUN) + && --timeout > 0) + udelay(1); + if (!timeout) + printk(KERN_ERR + "i2sbus: timed out turning " + "off dbdma engine!\n"); + } + pi->dbdma_ring.running = 0; list_for_each_entry(cii, &i2sdev->sound.codec_list, list) if (cii->codec->stop) cii->codec->stop(cii, pi->substream); @@ -622,82 +574,70 @@ static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in) fc = in_le32(&i2sdev->intfregs->frame_count); fc = fc - pi->frame_count; - if (fc >= pi->substream->runtime->buffer_size) - fc %= pi->substream->runtime->buffer_size; - return fc; + return (bytes_to_frames(pi->substream->runtime, + pi->current_period * + snd_pcm_lib_period_bytes(pi->substream)) + + fc) % pi->substream->runtime->buffer_size; } static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in) { struct pcm_info *pi; - u32 fc, nframes; - u32 status; - int timeout, i; - int dma_stopped = 0; - struct snd_pcm_runtime *runtime; + u32 fc; + u32 delta; spin_lock(&i2sdev->low_lock); get_pcm_info(i2sdev, in, &pi, NULL); - if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping) - goto out_unlock; - i = pi->current_period; - runtime = pi->substream->runtime; - while (pi->dbdma_ring.cmds[i].xfer_status) { - if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT) - /* - * BT is the branch taken bit. If it took a branch - * it is because we set the S0 bit to make it - * branch to the stop command. - */ - dma_stopped = 1; - pi->dbdma_ring.cmds[i].xfer_status = 0; - - if (++i >= runtime->periods) { - i = 0; - pi->frame_count += runtime->buffer_size; - } - pi->current_period = i; - - /* - * Check the frame count. The DMA tends to get a bit - * ahead of the frame counter, which confuses the core. - */ - fc = in_le32(&i2sdev->intfregs->frame_count); - nframes = i * runtime->period_size; - if (fc < pi->frame_count + nframes) - pi->frame_count = fc - nframes; + if (!pi->dbdma_ring.running) { + /* there was still an interrupt pending + * while we stopped. or maybe another + * processor (not the one that was stopping + * the DMA engine) was spinning above + * waiting for the lock. */ + goto out_unlock; } - if (dma_stopped) { - timeout = 1000; - for (;;) { - status = in_le32(&pi->dbdma->status); - if (!(status & ACTIVE) && (!in || (status & 0x80))) - break; - if (--timeout <= 0) { - printk(KERN_ERR "i2sbus: timed out " - "waiting for DMA to stop!\n"); - break; - } - udelay(1); + fc = in_le32(&i2sdev->intfregs->frame_count); + /* a counter overflow does not change the calculation. */ + delta = fc - pi->frame_count; + + /* update current_period */ + while (delta >= pi->substream->runtime->period_size) { + pi->current_period++; + delta = delta - pi->substream->runtime->period_size; + } + + if (unlikely(delta)) { + /* Some interrupt came late, so check the dbdma. + * This special case exists to syncronize the frame_count with + * the dbdma transfer, but is hit every once in a while. */ + int period; + + period = (in_le32(&pi->dbdma->cmdptr) + - pi->dbdma_ring.bus_cmd_start) + / sizeof(struct dbdma_cmd); + pi->current_period = pi->current_period + % pi->substream->runtime->periods; + + while (pi->current_period != period) { + pi->current_period++; + pi->current_period %= pi->substream->runtime->periods; + /* Set delta to zero, as the frame_count value is too + * high (otherwise the code path will not be executed). + * This corrects the fact that the frame_count is too + * low at the beginning due to buffering. */ + delta = 0; } - - /* Turn off DMA controller, clear S0 bit */ - out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16); - - pi->dbdma_ring.stopping = 0; - if (pi->stop_completion) - complete(pi->stop_completion); } - if (!pi->dbdma_ring.running) - goto out_unlock; + pi->frame_count = fc - delta; + pi->current_period %= pi->substream->runtime->periods; + spin_unlock(&i2sdev->low_lock); /* may call _trigger again, hence needs to be unlocked */ snd_pcm_period_elapsed(pi->substream); return; - out_unlock: spin_unlock(&i2sdev->low_lock); } @@ -778,7 +718,7 @@ static struct snd_pcm_ops i2sbus_playback_ops = { .close = i2sbus_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = i2sbus_hw_params, - .hw_free = i2sbus_playback_hw_free, + .hw_free = i2sbus_hw_free, .prepare = i2sbus_playback_prepare, .trigger = i2sbus_playback_trigger, .pointer = i2sbus_playback_pointer, @@ -848,7 +788,7 @@ static struct snd_pcm_ops i2sbus_record_ops = { .close = i2sbus_record_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = i2sbus_hw_params, - .hw_free = i2sbus_record_hw_free, + .hw_free = i2sbus_hw_free, .prepare = i2sbus_record_prepare, .trigger = i2sbus_record_trigger, .pointer = i2sbus_record_pointer, @@ -872,6 +812,7 @@ static void i2sbus_private_free(struct snd_pcm *pcm) module_put(THIS_MODULE); } +/* FIXME: this function needs an error handling strategy with labels */ int i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, struct codec_info *ci, void *data) @@ -939,31 +880,41 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, if (!cii->sdev) { printk(KERN_DEBUG "i2sbus: failed to get soundbus dev reference\n"); - err = -ENODEV; - goto out_free_cii; + kfree(cii); + return -ENODEV; } if (!try_module_get(THIS_MODULE)) { printk(KERN_DEBUG "i2sbus: failed to get module reference!\n"); - err = -EBUSY; - goto out_put_sdev; + soundbus_dev_put(dev); + kfree(cii); + return -EBUSY; } if (!try_module_get(ci->owner)) { printk(KERN_DEBUG "i2sbus: failed to get module reference to codec owner!\n"); - err = -EBUSY; - goto out_put_this_module; + module_put(THIS_MODULE); + soundbus_dev_put(dev); + kfree(cii); + return -EBUSY; } if (!dev->pcm) { - err = snd_pcm_new(card, dev->pcmname, dev->pcmid, 0, 0, + err = snd_pcm_new(card, + dev->pcmname, + dev->pcmid, + 0, + 0, &dev->pcm); if (err) { printk(KERN_DEBUG "i2sbus: failed to create pcm\n"); - goto out_put_ci_module; + kfree(cii); + module_put(ci->owner); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return err; } - dev->pcm->dev = &dev->ofdev.dev; } /* ALSA yet again sucks. @@ -975,12 +926,20 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, /* eh? */ printk(KERN_ERR "Can't attach same bus to different cards!\n"); - err = -EINVAL; - goto out_put_ci_module; + module_put(ci->owner); + kfree(cii); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return -EINVAL; + } + if ((err = + snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1))) { + module_put(ci->owner); + kfree(cii); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return err; } - err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1); - if (err) - goto out_put_ci_module; snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, &i2sbus_playback_ops); i2sdev->out.created = 1; @@ -990,11 +949,20 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, if (dev->pcm->card != card) { printk(KERN_ERR "Can't attach same bus to different cards!\n"); - goto out_put_ci_module; + module_put(ci->owner); + kfree(cii); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return -EINVAL; + } + if ((err = + snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1))) { + module_put(ci->owner); + kfree(cii); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return err; } - err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1); - if (err) - goto out_put_ci_module; snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, &i2sbus_record_ops); i2sdev->in.created = 1; @@ -1009,7 +977,11 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, err = snd_device_register(card, dev->pcm); if (err) { printk(KERN_ERR "i2sbus: error registering new pcm\n"); - goto out_put_ci_module; + module_put(ci->owner); + kfree(cii); + soundbus_dev_put(dev); + module_put(THIS_MODULE); + return err; } /* no errors any more, so let's add this to our list */ list_add(&cii->list, &dev->codec_list); @@ -1024,15 +996,6 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, 64 * 1024, 64 * 1024); return 0; - out_put_ci_module: - module_put(ci->owner); - out_put_this_module: - module_put(THIS_MODULE); - out_put_sdev: - soundbus_dev_put(dev); - out_free_cii: - kfree(cii); - return err; } void i2sbus_detach_codec(struct soundbus_dev *dev, void *data) diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h b/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h index ff29654782c9..ec20ee615d7f 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus.h @@ -10,7 +10,6 @@ #include #include #include -#include #include @@ -35,7 +34,6 @@ struct dbdma_command_mem { void *space; int size; u32 running:1; - u32 stopping:1; }; struct pcm_info { @@ -47,7 +45,6 @@ struct pcm_info { u32 frame_count; struct dbdma_command_mem dbdma_ring; volatile struct dbdma_regs __iomem *dbdma; - struct completion *stop_completion; }; enum { @@ -104,9 +101,6 @@ i2sbus_tx_intr(int irq, void *devid); extern irqreturn_t i2sbus_rx_intr(int irq, void *devid); -extern void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev); -extern void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev); - /* control specific functions */ extern int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c); diff --git a/trunk/sound/arm/aaci.h b/trunk/sound/arm/aaci.h index 9175ff9ded01..06295190606c 100644 --- a/trunk/sound/arm/aaci.h +++ b/trunk/sound/arm/aaci.h @@ -228,7 +228,7 @@ struct aaci { /* AC'97 */ struct mutex ac97_sem; - struct snd_ac97_bus *ac97_bus; + ac97_bus_t *ac97_bus; u32 maincr; spinlock_t lock; diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 42bcf2794b28..0c7bcd62e5b2 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -108,6 +108,7 @@ static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl) static int snd_ctl_release(struct inode *inode, struct file *file) { unsigned long flags; + struct list_head *list; struct snd_card *card; struct snd_ctl_file *ctl; struct snd_kcontrol *control; @@ -121,10 +122,12 @@ static int snd_ctl_release(struct inode *inode, struct file *file) list_del(&ctl->list); write_unlock_irqrestore(&card->ctl_files_rwlock, flags); down_write(&card->controls_rwsem); - list_for_each_entry(control, &card->controls, list) + list_for_each(list, &card->controls) { + control = snd_kcontrol(list); for (idx = 0; idx < control->count; idx++) if (control->vd[idx].owner == ctl) control->vd[idx].owner = NULL; + } up_write(&card->controls_rwsem); snd_ctl_empty_read_queue(ctl); kfree(ctl); @@ -137,6 +140,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, struct snd_ctl_elem_id *id) { unsigned long flags; + struct list_head *flist; struct snd_ctl_file *ctl; struct snd_kctl_event *ev; @@ -145,11 +149,14 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) card->mixer_oss_change_count++; #endif - list_for_each_entry(ctl, &card->ctl_files, list) { + list_for_each(flist, &card->ctl_files) { + struct list_head *elist; + ctl = snd_ctl_file(flist); if (!ctl->subscribed) continue; spin_lock_irqsave(&ctl->read_lock, flags); - list_for_each_entry(ev, &ctl->events, list) { + list_for_each(elist, &ctl->events) { + ev = snd_kctl_event(elist); if (ev->id.numid == id->numid) { ev->mask |= mask; goto _found; @@ -183,8 +190,7 @@ EXPORT_SYMBOL(snd_ctl_notify); * * Returns the pointer of the new instance, or NULL on failure. */ -static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, - unsigned int access) +struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int access) { struct snd_kcontrol *kctl; unsigned int idx; @@ -202,6 +208,8 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, return kctl; } +EXPORT_SYMBOL(snd_ctl_new); + /** * snd_ctl_new1 - create a control instance from the template * @ncontrol: the initialization record @@ -269,9 +277,11 @@ EXPORT_SYMBOL(snd_ctl_free_one); static unsigned int snd_ctl_hole_check(struct snd_card *card, unsigned int count) { + struct list_head *list; struct snd_kcontrol *kctl; - list_for_each_entry(kctl, &card->controls, list) { + list_for_each(list, &card->controls) { + kctl = snd_kcontrol(list); if ((kctl->id.numid <= card->last_numid && kctl->id.numid + kctl->count > card->last_numid) || (kctl->id.numid <= card->last_numid + count - 1 && @@ -488,10 +498,12 @@ EXPORT_SYMBOL(snd_ctl_rename_id); */ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid) { + struct list_head *list; struct snd_kcontrol *kctl; snd_assert(card != NULL && numid != 0, return NULL); - list_for_each_entry(kctl, &card->controls, list) { + list_for_each(list, &card->controls) { + kctl = snd_kcontrol(list); if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) return kctl; } @@ -515,12 +527,14 @@ EXPORT_SYMBOL(snd_ctl_find_numid); struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, struct snd_ctl_elem_id *id) { + struct list_head *list; struct snd_kcontrol *kctl; snd_assert(card != NULL && id != NULL, return NULL); if (id->numid != 0) return snd_ctl_find_numid(card, id->numid); - list_for_each_entry(kctl, &card->controls, list) { + list_for_each(list, &card->controls) { + kctl = snd_kcontrol(list); if (kctl->id.iface != id->iface) continue; if (kctl->id.device != id->device) @@ -1168,6 +1182,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg { struct snd_ctl_file *ctl; struct snd_card *card; + struct list_head *list; struct snd_kctl_ioctl *p; void __user *argp = (void __user *)arg; int __user *ip = argp; @@ -1217,7 +1232,8 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg #endif } down_read(&snd_ioctl_rwsem); - list_for_each_entry(p, &snd_control_ioctls, list) { + list_for_each(list, &snd_control_ioctls) { + p = list_entry(list, struct snd_kctl_ioctl, list); err = p->fioctl(card, ctl, cmd, arg); if (err != -ENOIOCTLCMD) { up_read(&snd_ioctl_rwsem); @@ -1341,11 +1357,13 @@ EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists) { + struct list_head *list; struct snd_kctl_ioctl *p; snd_assert(fcn != NULL, return -EINVAL); down_write(&snd_ioctl_rwsem); - list_for_each_entry(p, lists, list) { + list_for_each(list, lists) { + p = list_entry(list, struct snd_kctl_ioctl, list); if (p->fioctl == fcn) { list_del(&p->list); up_write(&snd_ioctl_rwsem); @@ -1435,6 +1453,7 @@ static int snd_ctl_dev_register(struct snd_device *device) static int snd_ctl_dev_disconnect(struct snd_device *device) { struct snd_card *card = device->device_data; + struct list_head *flist; struct snd_ctl_file *ctl; int err, cardnum; @@ -1443,7 +1462,8 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); down_read(&card->controls_rwsem); - list_for_each_entry(ctl, &card->ctl_files, list) { + list_for_each(flist, &card->ctl_files) { + ctl = snd_ctl_file(flist); wake_up(&ctl->change_sleep); kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); } diff --git a/trunk/sound/core/control_compat.c b/trunk/sound/core/control_compat.c index 9311ca397bbc..ab48962c48ce 100644 --- a/trunk/sound/core/control_compat.c +++ b/trunk/sound/core/control_compat.c @@ -392,7 +392,7 @@ enum { static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_ctl_file *ctl; - struct snd_kctl_ioctl *p; + struct list_head *list; void __user *argp = compat_ptr(arg); int err; @@ -427,7 +427,8 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns } down_read(&snd_ioctl_rwsem); - list_for_each_entry(p, &snd_control_compat_ioctls, list) { + list_for_each(list, &snd_control_compat_ioctls) { + struct snd_kctl_ioctl *p = list_entry(list, struct snd_kctl_ioctl, list); if (p->fioctl) { err = p->fioctl(ctl->card, ctl, cmd, arg); if (err != -ENOIOCTLCMD) { diff --git a/trunk/sound/core/device.c b/trunk/sound/core/device.c index 5858b02b0b1d..ccb25816ac9e 100644 --- a/trunk/sound/core/device.c +++ b/trunk/sound/core/device.c @@ -79,11 +79,13 @@ EXPORT_SYMBOL(snd_device_new); */ int snd_device_free(struct snd_card *card, void *device_data) { + struct list_head *list; struct snd_device *dev; snd_assert(card != NULL, return -ENXIO); snd_assert(device_data != NULL, return -ENXIO); - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (dev->device_data != device_data) continue; /* unlink */ @@ -122,11 +124,13 @@ EXPORT_SYMBOL(snd_device_free); */ int snd_device_disconnect(struct snd_card *card, void *device_data) { + struct list_head *list; struct snd_device *dev; snd_assert(card != NULL, return -ENXIO); snd_assert(device_data != NULL, return -ENXIO); - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (dev->device_data != device_data) continue; if (dev->state == SNDRV_DEV_REGISTERED && @@ -157,12 +161,14 @@ int snd_device_disconnect(struct snd_card *card, void *device_data) */ int snd_device_register(struct snd_card *card, void *device_data) { + struct list_head *list; struct snd_device *dev; int err; snd_assert(card != NULL, return -ENXIO); snd_assert(device_data != NULL, return -ENXIO); - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (dev->device_data != device_data) continue; if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { @@ -186,11 +192,13 @@ EXPORT_SYMBOL(snd_device_register); */ int snd_device_register_all(struct snd_card *card) { + struct list_head *list; struct snd_device *dev; int err; snd_assert(card != NULL, return -ENXIO); - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { if ((err = dev->ops->dev_register(dev)) < 0) return err; @@ -207,10 +215,12 @@ int snd_device_register_all(struct snd_card *card) int snd_device_disconnect_all(struct snd_card *card) { struct snd_device *dev; + struct list_head *list; int err = 0; snd_assert(card != NULL, return -ENXIO); - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (snd_device_disconnect(card, dev->device_data) < 0) err = -ENXIO; } @@ -224,6 +234,7 @@ int snd_device_disconnect_all(struct snd_card *card) int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd) { struct snd_device *dev; + struct list_head *list; int err; unsigned int range_low, range_high; @@ -231,7 +242,8 @@ int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd) range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE; range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1; __again: - list_for_each_entry(dev, &card->devices, list) { + list_for_each(list, &card->devices) { + dev = snd_device(list); if (dev->type >= range_low && dev->type <= range_high) { if ((err = snd_device_free(card, dev->device_data)) < 0) return err; diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index 39c03f3dfbfa..46b47689362c 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -47,11 +47,14 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device); static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device) { + struct list_head *p; struct snd_hwdep *hwdep; - list_for_each_entry(hwdep, &snd_hwdep_devices, list) + list_for_each(p, &snd_hwdep_devices) { + hwdep = list_entry(p, struct snd_hwdep, list); if (hwdep->card == card && hwdep->device == device) return hwdep; + } return NULL; } @@ -156,16 +159,15 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) int err = -ENXIO; struct snd_hwdep *hw = file->private_data; struct module *mod = hw->card->module; - mutex_lock(&hw->open_mutex); - if (hw->ops.release) + if (hw->ops.release) { err = hw->ops.release(hw, file); + wake_up(&hw->open_wait); + } if (hw->used > 0) hw->used--; - mutex_unlock(&hw->open_mutex); - wake_up(&hw->open_wait); - snd_card_file_remove(hw->card, file); + mutex_unlock(&hw->open_mutex); module_put(mod); return err; } @@ -466,12 +468,15 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) static void snd_hwdep_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { + struct list_head *p; struct snd_hwdep *hwdep; mutex_lock(®ister_mutex); - list_for_each_entry(hwdep, &snd_hwdep_devices, list) + list_for_each(p, &snd_hwdep_devices) { + hwdep = list_entry(p, struct snd_hwdep, list); snd_iprintf(buffer, "%02i-%02i: %s\n", hwdep->card->number, hwdep->device, hwdep->name); + } mutex_unlock(®ister_mutex); } diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index db6103733742..a4cc6b155ae9 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -114,28 +114,22 @@ struct snd_card *snd_card_new(int idx, const char *xid, if (idx < 0) { int idx2; for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) - /* idx == -1 == 0xffff means: take any free slot */ if (~snd_cards_lock & idx & 1<= snd_ecards_limit) snd_ecards_limit = idx + 1; break; } - } else { - if (idx < snd_ecards_limit) { - if (snd_cards_lock & (1 << idx)) - err = -EBUSY; /* invalid */ - } else { - if (idx < SNDRV_CARDS) - snd_ecards_limit = idx + 1; /* increase the limit */ - else - err = -ENODEV; - } - } + } else if (idx < snd_ecards_limit) { + if (snd_cards_lock & (1 << idx)) + err = -ENODEV; /* invalid */ + } else if (idx < SNDRV_CARDS) + snd_ecards_limit = idx + 1; /* increase the limit */ + else + err = -ENODEV; if (idx < 0 || err < 0) { mutex_unlock(&snd_card_mutex); - snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n", - idx, snd_ecards_limit - 1, err); + snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); goto __error; } snd_cards_lock |= 1 << idx; /* lock it */ diff --git a/trunk/sound/core/memalloc.c b/trunk/sound/core/memalloc.c index f057430db0d0..bc0bd0910a62 100644 --- a/trunk/sound/core/memalloc.c +++ b/trunk/sound/core/memalloc.c @@ -406,17 +406,19 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) */ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) { + struct list_head *p; struct snd_mem_list *mem; snd_assert(dmab, return 0); mutex_lock(&list_mutex); - list_for_each_entry(mem, &mem_list_head, list) { + list_for_each(p, &mem_list_head) { + mem = list_entry(p, struct snd_mem_list, list); if (mem->id == id && (mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL || ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) { struct device *dev = dmab->dev.dev; - list_del(&mem->list); + list_del(p); *dmab = mem->buffer; if (dmab->dev.dev == NULL) dmab->dev.dev = dev; @@ -486,6 +488,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, { int len = 0; long pages = snd_allocated_pages >> (PAGE_SHIFT-12); + struct list_head *p; struct snd_mem_list *mem; int devno; static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; @@ -495,7 +498,8 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, "pages : %li bytes (%li pages per %likB)\n", pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); devno = 0; - list_for_each_entry(mem, &mem_list_head, list) { + list_for_each(p, &mem_list_head) { + mem = list_entry(p, struct snd_mem_list, list); devno++; len += snprintf(page + len, count - len, "buffer %d : ID %08x : type %s\n", diff --git a/trunk/sound/core/misc.c b/trunk/sound/core/misc.c index 6db86a7c9704..03fc711f4127 100644 --- a/trunk/sound/core/misc.c +++ b/trunk/sound/core/misc.c @@ -78,31 +78,3 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) EXPORT_SYMBOL(snd_verbose_printd); #endif - -#ifdef CONFIG_PCI -#include -/** - * snd_pci_quirk_lookup - look up a PCI SSID quirk list - * @pci: pci_dev handle - * @list: quirk list, terminated by a null entry - * - * Look through the given quirk list and finds a matching entry - * with the same PCI SSID. When subdevice is 0, all subdevice - * values may match. - * - * Returns the matched entry pointer, or NULL if nothing matched. - */ -const struct snd_pci_quirk * -snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) -{ - const struct snd_pci_quirk *q; - - for (q = list; q->subvendor; q++) - if (q->subvendor == pci->subsystem_vendor && - (!q->subdevice || q->subdevice == pci->subsystem_device)) - return q; - return NULL; -} - -EXPORT_SYMBOL(snd_pci_quirk_lookup); -#endif diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 2743414fc8fa..8e0189885516 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -45,9 +45,11 @@ static int snd_pcm_dev_disconnect(struct snd_device *device); static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) { + struct list_head *p; struct snd_pcm *pcm; - list_for_each_entry(pcm, &snd_pcm_devices, list) { + list_for_each(p, &snd_pcm_devices) { + pcm = list_entry(p, struct snd_pcm, list); if (pcm->card == card && pcm->device == device) return pcm; } @@ -780,6 +782,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, struct snd_pcm_runtime *runtime; struct snd_ctl_file *kctl; struct snd_card *card; + struct list_head *list; int prefer_subdevice = -1; size_t size; @@ -792,7 +795,8 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, card = pcm->card; down_read(&card->controls_rwsem); - list_for_each_entry(kctl, &card->ctl_files, list) { + list_for_each(list, &card->ctl_files) { + kctl = snd_ctl_file(list); if (kctl->pid == current->pid) { prefer_subdevice = kctl->prefer_pcm_subdevice; if (prefer_subdevice != -1) @@ -937,10 +941,9 @@ static int snd_pcm_dev_register(struct snd_device *device) { int cidx, err; struct snd_pcm_substream *substream; - struct snd_pcm_notify *notify; + struct list_head *list; char str[16]; struct snd_pcm *pcm = device->device_data; - struct device *dev; snd_assert(pcm != NULL && device != NULL, return -ENXIO); mutex_lock(®ister_mutex); @@ -963,18 +966,11 @@ static int snd_pcm_dev_register(struct snd_device *device) devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE; break; } - /* device pointer to use, pcm->dev takes precedence if - * it is assigned, otherwise fall back to card's device - * if possible */ - dev = pcm->dev; - if (!dev) - dev = snd_card_get_device_link(pcm->card); - /* register pcm */ - err = snd_register_device_for_dev(devtype, pcm->card, - pcm->device, - &snd_pcm_f_ops[cidx], - pcm, str, dev); - if (err < 0) { + if ((err = snd_register_device(devtype, pcm->card, + pcm->device, + &snd_pcm_f_ops[cidx], + pcm, str)) < 0) + { list_del(&pcm->list); mutex_unlock(®ister_mutex); return err; @@ -984,10 +980,11 @@ static int snd_pcm_dev_register(struct snd_device *device) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) snd_pcm_timer_init(substream); } - - list_for_each_entry(notify, &snd_pcm_notify_list, list) + list_for_each(list, &snd_pcm_notify_list) { + struct snd_pcm_notify *notify; + notify = list_entry(list, struct snd_pcm_notify, list); notify->n_register(pcm); - + } mutex_unlock(®ister_mutex); return 0; } @@ -1030,7 +1027,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) { - struct snd_pcm *pcm; + struct list_head *p; snd_assert(notify != NULL && notify->n_register != NULL && @@ -1039,12 +1036,13 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) mutex_lock(®ister_mutex); if (nfree) { list_del(¬ify->list); - list_for_each_entry(pcm, &snd_pcm_devices, list) - notify->n_unregister(pcm); + list_for_each(p, &snd_pcm_devices) + notify->n_unregister(list_entry(p, + struct snd_pcm, list)); } else { list_add_tail(¬ify->list, &snd_pcm_notify_list); - list_for_each_entry(pcm, &snd_pcm_devices, list) - notify->n_register(pcm); + list_for_each(p, &snd_pcm_devices) + notify->n_register(list_entry(p, struct snd_pcm, list)); } mutex_unlock(®ister_mutex); return 0; @@ -1060,10 +1058,12 @@ EXPORT_SYMBOL(snd_pcm_notify); static void snd_pcm_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { + struct list_head *p; struct snd_pcm *pcm; mutex_lock(®ister_mutex); - list_for_each_entry(pcm, &snd_pcm_devices, list) { + list_for_each(p, &snd_pcm_devices) { + pcm = list_entry(p, struct snd_pcm, list); snd_iprintf(buffer, "%02i-%02i: %s : %s", pcm->card->number, pcm->device, pcm->id, pcm->name); if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) diff --git a/trunk/sound/core/pcm_lib.c b/trunk/sound/core/pcm_lib.c index 9fefcaa2c324..b336797be4fc 100644 --- a/trunk/sound/core/pcm_lib.c +++ b/trunk/sound/core/pcm_lib.c @@ -781,11 +781,6 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int * { unsigned int k; int changed = 0; - - if (!count) { - i->empty = 1; - return -EINVAL; - } for (k = 0; k < count; k++) { if (mask && !(mask & (1 << k))) continue; diff --git a/trunk/sound/core/pcm_memory.c b/trunk/sound/core/pcm_memory.c index 95b1b2f0b1e2..be030cb4d373 100644 --- a/trunk/sound/core/pcm_memory.c +++ b/trunk/sound/core/pcm_memory.c @@ -101,8 +101,6 @@ int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) { snd_pcm_lib_preallocate_dma_free(substream); #ifdef CONFIG_SND_VERBOSE_PROCFS - snd_info_free_entry(substream->proc_prealloc_max_entry); - substream->proc_prealloc_max_entry = NULL; snd_info_free_entry(substream->proc_prealloc_entry); substream->proc_prealloc_entry = NULL; #endif @@ -143,18 +141,6 @@ static void snd_pcm_lib_preallocate_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_buffer.bytes / 1024); } -/* - * read callback for prealloc_max proc file - * - * prints the maximum allowed size in kB. - */ -static void snd_pcm_lib_preallocate_max_proc_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_pcm_substream *substream = entry->private_data; - snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_max / 1024); -} - /* * write callback for prealloc proc file * @@ -217,15 +203,6 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream) } } substream->proc_prealloc_entry = entry; - if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc_max", substream->proc_root)) != NULL) { - entry->c.text.read = snd_pcm_lib_preallocate_max_proc_read; - entry->private_data = substream; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - substream->proc_prealloc_max_entry = entry; } #else /* !CONFIG_SND_VERBOSE_PROCFS */ diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index 7e6ceec738d5..0f055bfcbdac 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -61,11 +61,14 @@ static DEFINE_MUTEX(register_mutex); static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { + struct list_head *p; struct snd_rawmidi *rawmidi; - list_for_each_entry(rawmidi, &snd_rawmidi_devices, list) + list_for_each(p, &snd_rawmidi_devices) { + rawmidi = list_entry(p, struct snd_rawmidi, list); if (rawmidi->card == card && rawmidi->device == device) return rawmidi; + } return NULL; } @@ -386,6 +389,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) struct snd_rawmidi *rmidi; struct snd_rawmidi_file *rawmidi_file; wait_queue_t wait; + struct list_head *list; struct snd_ctl_file *kctl; if (maj == snd_major) { @@ -422,7 +426,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) while (1) { subdevice = -1; down_read(&card->controls_rwsem); - list_for_each_entry(kctl, &card->ctl_files, list) { + list_for_each(list, &card->ctl_files) { + kctl = snd_ctl_file(list); if (kctl->pid == current->pid) { subdevice = kctl->prefer_rawmidi_subdevice; if (subdevice != -1) @@ -570,6 +575,7 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info struct snd_rawmidi *rmidi; struct snd_rawmidi_str *pstr; struct snd_rawmidi_substream *substream; + struct list_head *list; mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, info->device); @@ -583,7 +589,8 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info return -ENOENT; if (info->subdevice >= pstr->substream_count) return -ENXIO; - list_for_each_entry(substream, &pstr->substreams, list) { + list_for_each(list, &pstr->substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); if ((unsigned int)substream->number == info->subdevice) return snd_rawmidi_info(substream, info); } @@ -1306,14 +1313,14 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *substream; struct snd_rawmidi_runtime *runtime; + struct list_head *list; rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); mutex_lock(&rmidi->open_mutex); if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { - list_for_each_entry(substream, - &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams, - list) { + list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); snd_iprintf(buffer, "Output %d\n" " Tx bytes : %lu\n", @@ -1332,9 +1339,8 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, } } if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) { - list_for_each_entry(substream, - &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams, - list) { + list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); snd_iprintf(buffer, "Input %d\n" " Rx bytes : %lu\n", @@ -1619,10 +1625,13 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream, struct snd_rawmidi_ops *ops) { + struct list_head *list; struct snd_rawmidi_substream *substream; - list_for_each_entry(substream, &rmidi->streams[stream].substreams, list) + list_for_each(list, &rmidi->streams[stream].substreams) { + substream = list_entry(list, struct snd_rawmidi_substream, list); substream->ops = ops; + } } /* diff --git a/trunk/sound/core/seq/seq_clientmgr.c b/trunk/sound/core/seq/seq_clientmgr.c index bb9dd9fa8e51..532a660df51d 100644 --- a/trunk/sound/core/seq/seq_clientmgr.c +++ b/trunk/sound/core/seq/seq_clientmgr.c @@ -659,6 +659,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client, int err = 0, num_ev = 0; struct snd_seq_event event_saved; struct snd_seq_client_port *src_port; + struct list_head *p; struct snd_seq_port_subs_info *grp; src_port = snd_seq_port_use_ptr(client, event->source.port); @@ -673,7 +674,8 @@ static int deliver_to_subscribers(struct snd_seq_client *client, read_lock(&grp->list_lock); else down_read(&grp->list_mutex); - list_for_each_entry(subs, &grp->list_head, src_list) { + list_for_each(p, &grp->list_head) { + subs = list_entry(p, struct snd_seq_subscribers, src_list); event->dest = subs->info.dest; if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) /* convert time according to flag with subscription */ @@ -707,14 +709,15 @@ static int port_broadcast_event(struct snd_seq_client *client, { int num_ev = 0, err = 0; struct snd_seq_client *dest_client; - struct snd_seq_client_port *port; + struct list_head *p; dest_client = get_event_dest_client(event, SNDRV_SEQ_FILTER_BROADCAST); if (dest_client == NULL) return 0; /* no matching destination */ read_lock(&dest_client->ports_lock); - list_for_each_entry(port, &dest_client->ports_list_head, list) { + list_for_each(p, &dest_client->ports_list_head) { + struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list); event->dest.port = port->addr.port; /* pass NULL as source client to avoid error bounce */ err = snd_seq_deliver_single_event(NULL, event, @@ -2470,10 +2473,11 @@ static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer, static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, struct snd_seq_client *client) { - struct snd_seq_client_port *p; + struct list_head *l; mutex_lock(&client->ports_mutex); - list_for_each_entry(p, &client->ports_list_head, list) { + list_for_each(l, &client->ports_list_head) { + struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", p->addr.port, p->name, FLAG_PERM_RD(p->capability), diff --git a/trunk/sound/core/seq/seq_device.c b/trunk/sound/core/seq/seq_device.c index 37852cdace76..b79d011813c0 100644 --- a/trunk/sound/core/seq/seq_device.c +++ b/trunk/sound/core/seq/seq_device.c @@ -106,10 +106,11 @@ static void remove_drivers(void); static void snd_seq_device_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { - struct ops_list *ops; + struct list_head *head; mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { + list_for_each(head, &opslist) { + struct ops_list *ops = list_entry(head, struct ops_list, list); snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", ops->id, ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""), @@ -142,7 +143,7 @@ void snd_seq_autoload_unlock(void) void snd_seq_device_load_drivers(void) { #ifdef CONFIG_KMOD - struct ops_list *ops; + struct list_head *head; /* Calling request_module during module_init() * may cause blocking. @@ -154,7 +155,8 @@ void snd_seq_device_load_drivers(void) return; mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { + list_for_each(head, &opslist) { + struct ops_list *ops = list_entry(head, struct ops_list, list); if (! (ops->driver & DRIVER_LOADED) && ! (ops->driver & DRIVER_REQUESTED)) { ops->used++; @@ -312,8 +314,8 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device) int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize) { + struct list_head *head; struct ops_list *ops; - struct snd_seq_device *dev; if (id == NULL || entry == NULL || entry->init_device == NULL || entry->free_device == NULL) @@ -339,7 +341,8 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, ops->argsize = argsize; /* initialize existing devices if necessary */ - list_for_each_entry(dev, &ops->dev_list, list) { + list_for_each(head, &ops->dev_list) { + struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); init_device(dev, ops); } mutex_unlock(&ops->reg_mutex); @@ -391,8 +394,8 @@ static struct ops_list * create_driver(char *id) */ int snd_seq_device_unregister_driver(char *id) { + struct list_head *head; struct ops_list *ops; - struct snd_seq_device *dev; ops = find_driver(id, 0); if (ops == NULL) @@ -408,7 +411,8 @@ int snd_seq_device_unregister_driver(char *id) /* close and release all devices associated with this driver */ mutex_lock(&ops->reg_mutex); ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ - list_for_each_entry(dev, &ops->dev_list, list) { + list_for_each(head, &ops->dev_list) { + struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); free_device(dev, ops); } @@ -508,10 +512,11 @@ static int free_device(struct snd_seq_device *dev, struct ops_list *ops) */ static struct ops_list * find_driver(char *id, int create_if_empty) { - struct ops_list *ops; + struct list_head *head; mutex_lock(&ops_mutex); - list_for_each_entry(ops, &opslist, list) { + list_for_each(head, &opslist) { + struct ops_list *ops = list_entry(head, struct ops_list, list); if (strcmp(ops->id, id) == 0) { ops->used++; mutex_unlock(&ops_mutex); diff --git a/trunk/sound/core/seq/seq_ports.c b/trunk/sound/core/seq/seq_ports.c index eefd1cf872b4..8c64b58ff77b 100644 --- a/trunk/sound/core/seq/seq_ports.c +++ b/trunk/sound/core/seq/seq_ports.c @@ -59,12 +59,14 @@ much elements are in array. struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num) { + struct list_head *p; struct snd_seq_client_port *port; if (client == NULL) return NULL; read_lock(&client->ports_lock); - list_for_each_entry(port, &client->ports_list_head, list) { + list_for_each(p, &client->ports_list_head) { + port = list_entry(p, struct snd_seq_client_port, list); if (port->addr.port == num) { if (port->closing) break; /* deleting now */ @@ -83,12 +85,14 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl struct snd_seq_port_info *pinfo) { int num; + struct list_head *p; struct snd_seq_client_port *port, *found; num = pinfo->addr.port; found = NULL; read_lock(&client->ports_lock); - list_for_each_entry(port, &client->ports_list_head, list) { + list_for_each(p, &client->ports_list_head) { + port = list_entry(p, struct snd_seq_client_port, list); if (port->addr.port < num) continue; if (port->addr.port == num) { @@ -127,7 +131,8 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port) { unsigned long flags; - struct snd_seq_client_port *new_port, *p; + struct snd_seq_client_port *new_port; + struct list_head *l; int num = -1; /* sanity check */ @@ -156,14 +161,15 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, num = port >= 0 ? port : 0; mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); - list_for_each_entry(p, &client->ports_list_head, list) { + list_for_each(l, &client->ports_list_head) { + struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); if (p->addr.port > num) break; if (port < 0) /* auto-probe mode */ num = p->addr.port + 1; } /* insert the new port */ - list_add_tail(&new_port->list, &p->list); + list_add_tail(&new_port->list, l); client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ write_unlock_irqrestore(&client->ports_lock, flags); @@ -245,9 +251,9 @@ static void clear_subscriber_list(struct snd_seq_client *client, list_del(&subs->dest_list); else list_del(&subs->src_list); - up_write(&agrp->list_mutex); unsubscribe_port(c, aport, agrp, &subs->info, 1); kfree(subs); + up_write(&agrp->list_mutex); snd_seq_port_unlock(aport); snd_seq_client_unlock(c); } @@ -281,14 +287,16 @@ static int port_delete(struct snd_seq_client *client, int snd_seq_delete_port(struct snd_seq_client *client, int port) { unsigned long flags; - struct snd_seq_client_port *found = NULL, *p; + struct list_head *l; + struct snd_seq_client_port *found = NULL; mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); - list_for_each_entry(p, &client->ports_list_head, list) { + list_for_each(l, &client->ports_list_head) { + struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); if (p->addr.port == port) { /* ok found. delete from the list at first */ - list_del(&p->list); + list_del(l); client->num_ports--; found = p; break; @@ -306,8 +314,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) int snd_seq_delete_all_ports(struct snd_seq_client *client) { unsigned long flags; - struct list_head deleted_list; - struct snd_seq_client_port *port, *tmp; + struct list_head deleted_list, *p, *n; /* move the port list to deleted_list, and * clear the port list in the client data. @@ -324,8 +331,9 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) write_unlock_irqrestore(&client->ports_lock, flags); /* remove each port in deleted_list */ - list_for_each_entry_safe(port, tmp, &deleted_list, list) { - list_del(&port->list); + list_for_each_safe(p, n, &deleted_list) { + struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list); + list_del(p); snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); port_delete(client, port); } @@ -492,7 +500,8 @@ int snd_seq_port_connect(struct snd_seq_client *connector, { struct snd_seq_port_subs_info *src = &src_port->c_src; struct snd_seq_port_subs_info *dest = &dest_port->c_dest; - struct snd_seq_subscribers *subs, *s; + struct snd_seq_subscribers *subs; + struct list_head *p; int err, src_called = 0; unsigned long flags; int exclusive; @@ -516,11 +525,13 @@ int snd_seq_port_connect(struct snd_seq_client *connector, if (src->exclusive || dest->exclusive) goto __error; /* check whether already exists */ - list_for_each_entry(s, &src->list_head, src_list) { + list_for_each(p, &src->list_head) { + struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, src_list); if (match_subs_info(info, &s->info)) goto __error; } - list_for_each_entry(s, &dest->list_head, dest_list) { + list_for_each(p, &dest->list_head) { + struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, dest_list); if (match_subs_info(info, &s->info)) goto __error; } @@ -571,6 +582,7 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, struct snd_seq_port_subs_info *src = &src_port->c_src; struct snd_seq_port_subs_info *dest = &dest_port->c_dest; struct snd_seq_subscribers *subs; + struct list_head *p; int err = -ENOENT; unsigned long flags; @@ -578,7 +590,8 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, down_write_nested(&dest->list_mutex, SINGLE_DEPTH_NESTING); /* look for the connection */ - list_for_each_entry(subs, &src->list_head, src_list) { + list_for_each(p, &src->list_head) { + subs = list_entry(p, struct snd_seq_subscribers, src_list); if (match_subs_info(info, &subs->info)) { write_lock_irqsave(&src->list_lock, flags); // write_lock(&dest->list_lock); // no lock yet @@ -607,10 +620,12 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp, struct snd_seq_addr *dest_addr) { + struct list_head *p; struct snd_seq_subscribers *s, *found = NULL; down_read(&src_grp->list_mutex); - list_for_each_entry(s, &src_grp->list_head, src_list) { + list_for_each(p, &src_grp->list_head) { + s = list_entry(p, struct snd_seq_subscribers, src_list); if (addr_match(dest_addr, &s->info.dest)) { found = s; break; diff --git a/trunk/sound/core/seq/seq_virmidi.c b/trunk/sound/core/seq/seq_virmidi.c index 972f93405364..0cfa06c6b81f 100644 --- a/trunk/sound/core/seq/seq_virmidi.c +++ b/trunk/sound/core/seq/seq_virmidi.c @@ -81,11 +81,13 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, struct snd_seq_event *ev) { struct snd_virmidi *vmidi; + struct list_head *list; unsigned char msg[4]; int len; read_lock(&rdev->filelist_lock); - list_for_each_entry(vmidi, &rdev->filelist, list) { + list_for_each(list, &rdev->filelist) { + vmidi = list_entry(list, struct snd_virmidi, list); if (!vmidi->trigger) continue; if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 4084de064127..82a61c67cf3a 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -219,27 +219,26 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) #endif /** - * snd_register_device_for_dev - Register the ALSA device file for the card + * snd_register_device - Register the ALSA device file for the card * @type: the device type, SNDRV_DEVICE_TYPE_XXX * @card: the card instance * @dev: the device index * @f_ops: the file operations * @private_data: user pointer for f_ops->open() * @name: the device file name - * @device: the &struct device to link this new device to * * Registers an ALSA device file for the given card. * The operators have to be set in reg parameter. * - * Returns zero if successful, or a negative error code on failure. + * Retrurns zero if successful, or a negative error code on failure. */ -int snd_register_device_for_dev(int type, struct snd_card *card, int dev, - const struct file_operations *f_ops, - void *private_data, - const char *name, struct device *device) +int snd_register_device(int type, struct snd_card *card, int dev, + const struct file_operations *f_ops, void *private_data, + const char *name) { int minor; struct snd_minor *preg; + struct device *device = snd_card_get_device_link(card); snd_assert(name, return -EINVAL); preg = kmalloc(sizeof *preg, GFP_KERNEL); @@ -273,7 +272,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, return 0; } -EXPORT_SYMBOL(snd_register_device_for_dev); +EXPORT_SYMBOL(snd_register_device); /* find the matching minor record * return the index of snd_minor, or -1 if not found diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index 3e0638351069..10a79aed33f8 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef CONFIG_KERNELD +#include +#endif #if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE) #define DEFAULT_TIMER_LIMIT 3 @@ -127,8 +130,11 @@ static struct snd_timer_instance *snd_timer_instance_new(char *owner, static struct snd_timer *snd_timer_find(struct snd_timer_id *tid) { struct snd_timer *timer = NULL; + struct list_head *p; + + list_for_each(p, &snd_timer_list) { + timer = list_entry(p, struct snd_timer, device_list); - list_for_each_entry(timer, &snd_timer_list, device_list) { if (timer->tmr_class != tid->dev_class) continue; if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD || @@ -178,10 +184,13 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) { struct snd_timer *timer; struct snd_timer_instance *master; + struct list_head *p, *q; /* FIXME: it's really dumb to look up all entries.. */ - list_for_each_entry(timer, &snd_timer_list, device_list) { - list_for_each_entry(master, &timer->open_list_head, open_list) { + list_for_each(p, &snd_timer_list) { + timer = list_entry(p, struct snd_timer, device_list); + list_for_each(q, &timer->open_list_head) { + master = list_entry(q, struct snd_timer_instance, open_list); if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { list_del(&slave->open_list); @@ -205,13 +214,16 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) */ static void snd_timer_check_master(struct snd_timer_instance *master) { - struct snd_timer_instance *slave, *tmp; + struct snd_timer_instance *slave; + struct list_head *p, *n; /* check all pending slaves */ - list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) { + list_for_each_safe(p, n, &snd_timer_slave_list) { + slave = list_entry(p, struct snd_timer_instance, open_list); if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { - list_move_tail(&slave->open_list, &master->slave_list_head); + list_del(p); + list_add_tail(p, &master->slave_list_head); spin_lock_irq(&slave_active_lock); slave->master = master; slave->timer = master->timer; @@ -305,7 +317,8 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int snd_timer_close(struct snd_timer_instance *timeri) { struct snd_timer *timer = NULL; - struct snd_timer_instance *slave, *tmp; + struct list_head *p, *n; + struct snd_timer_instance *slave; snd_assert(timeri != NULL, return -ENXIO); @@ -340,11 +353,12 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer->hw.close) timer->hw.close(timer); /* remove slave links */ - list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, - open_list) { + list_for_each_safe(p, n, &timeri->slave_list_head) { + slave = list_entry(p, struct snd_timer_instance, open_list); spin_lock_irq(&slave_active_lock); _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); - list_move_tail(&slave->open_list, &snd_timer_slave_list); + list_del(p); + list_add_tail(p, &snd_timer_slave_list); slave->master = NULL; slave->timer = NULL; spin_unlock_irq(&slave_active_lock); @@ -380,6 +394,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) unsigned long flags; unsigned long resolution = 0; struct snd_timer_instance *ts; + struct list_head *n; struct timespec tstamp; getnstimeofday(&tstamp); @@ -398,9 +413,11 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) return; spin_lock_irqsave(&timer->lock, flags); - list_for_each_entry(ts, &ti->slave_active_head, active_list) + list_for_each(n, &ti->slave_active_head) { + ts = list_entry(n, struct snd_timer_instance, active_list); if (ts->ccallback) ts->ccallback(ti, event + 100, &tstamp, resolution); + } spin_unlock_irqrestore(&timer->lock, flags); } @@ -576,8 +593,10 @@ static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_l { struct snd_timer_instance *ti; unsigned long ticks = ~0UL; + struct list_head *p; - list_for_each_entry(ti, &timer->active_list_head, active_list) { + list_for_each(p, &timer->active_list_head) { + ti = list_entry(p, struct snd_timer_instance, active_list); if (ti->flags & SNDRV_TIMER_IFLG_START) { ti->flags &= ~SNDRV_TIMER_IFLG_START; ti->flags |= SNDRV_TIMER_IFLG_RUNNING; @@ -642,9 +661,9 @@ static void snd_timer_tasklet(unsigned long arg) */ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) { - struct snd_timer_instance *ti, *ts, *tmp; + struct snd_timer_instance *ti, *ts; unsigned long resolution, ticks; - struct list_head *p, *ack_list_head; + struct list_head *p, *q, *n, *ack_list_head; unsigned long flags; int use_tasklet = 0; @@ -660,12 +679,12 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) resolution = timer->hw.resolution; /* loop for all active instances - * Here we cannot use list_for_each_entry because the active_list of a + * Here we cannot use list_for_each because the active_list of a * processed instance is relinked to done_list_head before the callback * is called. */ - list_for_each_entry_safe(ti, tmp, &timer->active_list_head, - active_list) { + list_for_each_safe(p, n, &timer->active_list_head) { + ti = list_entry(p, struct snd_timer_instance, active_list); if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) continue; ti->pticks += ticks_left; @@ -681,7 +700,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) } else { ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; if (--timer->running) - list_del(&ti->active_list); + list_del(p); } if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) @@ -690,7 +709,8 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) ack_list_head = &timer->sack_list_head; if (list_empty(&ti->ack_list)) list_add_tail(&ti->ack_list, ack_list_head); - list_for_each_entry(ts, &ti->slave_active_head, active_list) { + list_for_each(q, &ti->slave_active_head) { + ts = list_entry(q, struct snd_timer_instance, active_list); ts->pticks = ti->pticks; ts->resolution = resolution; if (list_empty(&ts->ack_list)) @@ -824,6 +844,7 @@ static int snd_timer_dev_register(struct snd_device *dev) { struct snd_timer *timer = dev->device_data; struct snd_timer *timer1; + struct list_head *p; snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); @@ -832,7 +853,8 @@ static int snd_timer_dev_register(struct snd_device *dev) return -EINVAL; mutex_lock(®ister_mutex); - list_for_each_entry(timer1, &snd_timer_list, device_list) { + list_for_each(p, &snd_timer_list) { + timer1 = list_entry(p, struct snd_timer, device_list); if (timer1->tmr_class > timer->tmr_class) break; if (timer1->tmr_class < timer->tmr_class) @@ -855,7 +877,7 @@ static int snd_timer_dev_register(struct snd_device *dev) mutex_unlock(®ister_mutex); return -EBUSY; } - list_add_tail(&timer->device_list, &timer1->device_list); + list_add_tail(&timer->device_list, p); mutex_unlock(®ister_mutex); return 0; } @@ -874,6 +896,7 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam unsigned long flags; unsigned long resolution = 0; struct snd_timer_instance *ti, *ts; + struct list_head *p, *n; if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) return; @@ -888,12 +911,15 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam else resolution = timer->hw.resolution; } - list_for_each_entry(ti, &timer->active_list_head, active_list) { + list_for_each(p, &timer->active_list_head) { + ti = list_entry(p, struct snd_timer_instance, active_list); if (ti->ccallback) ti->ccallback(ti, event, tstamp, resolution); - list_for_each_entry(ts, &ti->slave_active_head, active_list) + list_for_each(n, &ti->slave_active_head) { + ts = list_entry(n, struct snd_timer_instance, active_list); if (ts->ccallback) ts->ccallback(ts, event, tstamp, resolution); + } } spin_unlock_irqrestore(&timer->lock, flags); } @@ -1031,9 +1057,11 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, { struct snd_timer *timer; struct snd_timer_instance *ti; + struct list_head *p, *q; mutex_lock(®ister_mutex); - list_for_each_entry(timer, &snd_timer_list, device_list) { + list_for_each(p, &snd_timer_list) { + timer = list_entry(p, struct snd_timer, device_list); switch (timer->tmr_class) { case SNDRV_TIMER_CLASS_GLOBAL: snd_iprintf(buffer, "G%i: ", timer->tmr_device); @@ -1060,12 +1088,14 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) snd_iprintf(buffer, " SLAVE"); snd_iprintf(buffer, "\n"); - list_for_each_entry(ti, &timer->open_list_head, open_list) + list_for_each(q, &timer->open_list_head) { + ti = list_entry(q, struct snd_timer_instance, open_list); snd_iprintf(buffer, " Client %s : %s\n", ti->owner ? ti->owner : "unknown", ti->flags & (SNDRV_TIMER_IFLG_START | SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped"); + } } mutex_unlock(®ister_mutex); } diff --git a/trunk/sound/drivers/Kconfig b/trunk/sound/drivers/Kconfig index 83529b08d019..40ebd2f44056 100644 --- a/trunk/sound/drivers/Kconfig +++ b/trunk/sound/drivers/Kconfig @@ -109,15 +109,4 @@ config SND_MPU401 To compile this driver as a module, choose M here: the module will be called snd-mpu401. -config SND_PORTMAN2X4 - tristate "Portman 2x4 driver" - depends on SND && PARPORT - select SND_RAWMIDI - help - Say Y here to include support for Midiman Portman 2x4 parallel - port MIDI device. - - To compile this driver as a module, choose M here: the module - will be called snd-portman2x4. - endmenu diff --git a/trunk/sound/drivers/Makefile b/trunk/sound/drivers/Makefile index 04112642611a..c9bad6d67e73 100644 --- a/trunk/sound/drivers/Makefile +++ b/trunk/sound/drivers/Makefile @@ -6,7 +6,6 @@ snd-dummy-objs := dummy.o snd-mtpav-objs := mtpav.o snd-mts64-objs := mts64.o -snd-portman2x4-objs := portman2x4.o snd-serial-u16550-objs := serial-u16550.o snd-virmidi-objs := virmidi.o @@ -16,6 +15,5 @@ obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o obj-$(CONFIG_SND_MTS64) += snd-mts64.o -obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/ diff --git a/trunk/sound/drivers/dummy.c b/trunk/sound/drivers/dummy.c index 8339bad969ba..42001efa9f3e 100644 --- a/trunk/sound/drivers/dummy.c +++ b/trunk/sound/drivers/dummy.c @@ -501,7 +501,7 @@ static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol, return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0); +static DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0); #define DUMMY_CAPSRC(xname, xindex, addr) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ diff --git a/trunk/sound/drivers/portman2x4.c b/trunk/sound/drivers/portman2x4.c deleted file mode 100644 index 6c48772aaefd..000000000000 --- a/trunk/sound/drivers/portman2x4.c +++ /dev/null @@ -1,876 +0,0 @@ -/* - * Driver for Midiman Portman2x4 parallel port midi interface - * - * Copyright (c) by Levent Guendogdu - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * ChangeLog - * Jan 24 2007 Matthias Koenig - * - cleanup and rewrite - * Sep 30 2004 Tobias Gehrig - * - source code cleanup - * Sep 03 2004 Tobias Gehrig - * - fixed compilation problem with alsa 1.0.6a (removed MODULE_CLASSES, - * MODULE_PARM_SYNTAX and changed MODULE_DEVICES to - * MODULE_SUPPORTED_DEVICE) - * Mar 24 2004 Tobias Gehrig - * - added 2.6 kernel support - * Mar 18 2004 Tobias Gehrig - * - added parport_unregister_driver to the startup routine if the driver fails to detect a portman - * - added support for all 4 output ports in portman_putmidi - * Mar 17 2004 Tobias Gehrig - * - added checks for opened input device in interrupt handler - * Feb 20 2004 Tobias Gehrig - * - ported from alsa 0.5 to 1.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CARD_NAME "Portman 2x4" -#define DRIVER_NAME "portman" -#define PLATFORM_DRIVER "snd_portman2x4" - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -static struct platform_device *platform_devices[SNDRV_CARDS]; -static int device_count; - -module_param_array(index, int, NULL, S_IRUGO); -MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); -module_param_array(id, charp, NULL, S_IRUGO); -MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); -module_param_array(enable, bool, NULL, S_IRUGO); -MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); - -MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig"); -MODULE_DESCRIPTION("Midiman Portman2x4"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Midiman,Portman2x4}}"); - -/********************************************************************* - * Chip specific - *********************************************************************/ -#define PORTMAN_NUM_INPUT_PORTS 2 -#define PORTMAN_NUM_OUTPUT_PORTS 4 - -struct portman { - spinlock_t reg_lock; - struct snd_card *card; - struct snd_rawmidi *rmidi; - struct pardevice *pardev; - int pardev_claimed; - - int open_count; - int mode[PORTMAN_NUM_INPUT_PORTS]; - struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS]; -}; - -static int portman_free(struct portman *pm) -{ - kfree(pm); - return 0; -} - -static int __devinit portman_create(struct snd_card *card, - struct pardevice *pardev, - struct portman **rchip) -{ - struct portman *pm; - - *rchip = NULL; - - pm = kzalloc(sizeof(struct portman), GFP_KERNEL); - if (pm == NULL) - return -ENOMEM; - - /* Init chip specific data */ - spin_lock_init(&pm->reg_lock); - pm->card = card; - pm->pardev = pardev; - - *rchip = pm; - - return 0; -} - -/********************************************************************* - * HW related constants - *********************************************************************/ - -/* Standard PC parallel port status register equates. */ -#define PP_STAT_BSY 0x80 /* Busy status. Inverted. */ -#define PP_STAT_ACK 0x40 /* Acknowledge. Non-Inverted. */ -#define PP_STAT_POUT 0x20 /* Paper Out. Non-Inverted. */ -#define PP_STAT_SEL 0x10 /* Select. Non-Inverted. */ -#define PP_STAT_ERR 0x08 /* Error. Non-Inverted. */ - -/* Standard PC parallel port command register equates. */ -#define PP_CMD_IEN 0x10 /* IRQ Enable. Non-Inverted. */ -#define PP_CMD_SELI 0x08 /* Select Input. Inverted. */ -#define PP_CMD_INIT 0x04 /* Init Printer. Non-Inverted. */ -#define PP_CMD_FEED 0x02 /* Auto Feed. Inverted. */ -#define PP_CMD_STB 0x01 /* Strobe. Inverted. */ - -/* Parallel Port Command Register as implemented by PCP2x4. */ -#define INT_EN PP_CMD_IEN /* Interrupt enable. */ -#define STROBE PP_CMD_STB /* Command strobe. */ - -/* The parallel port command register field (b1..b3) selects the - * various "registers" within the PC/P 2x4. These are the internal - * address of these "registers" that must be written to the parallel - * port command register. - */ -#define RXDATA0 (0 << 1) /* PCP RxData channel 0. */ -#define RXDATA1 (1 << 1) /* PCP RxData channel 1. */ -#define GEN_CTL (2 << 1) /* PCP General Control Register. */ -#define SYNC_CTL (3 << 1) /* PCP Sync Control Register. */ -#define TXDATA0 (4 << 1) /* PCP TxData channel 0. */ -#define TXDATA1 (5 << 1) /* PCP TxData channel 1. */ -#define TXDATA2 (6 << 1) /* PCP TxData channel 2. */ -#define TXDATA3 (7 << 1) /* PCP TxData channel 3. */ - -/* Parallel Port Status Register as implemented by PCP2x4. */ -#define ESTB PP_STAT_POUT /* Echoed strobe. */ -#define INT_REQ PP_STAT_ACK /* Input data int request. */ -#define BUSY PP_STAT_ERR /* Interface Busy. */ - -/* Parallel Port Status Register BUSY and SELECT lines are multiplexed - * between several functions. Depending on which 2x4 "register" is - * currently selected (b1..b3), the BUSY and SELECT lines are - * assigned as follows: - * - * SELECT LINE: A3 A2 A1 - * -------- - */ -#define RXAVAIL PP_STAT_SEL /* Rx Available, channel 0. 0 0 0 */ -// RXAVAIL1 PP_STAT_SEL /* Rx Available, channel 1. 0 0 1 */ -#define SYNC_STAT PP_STAT_SEL /* Reserved - Sync Status. 0 1 0 */ -// /* Reserved. 0 1 1 */ -#define TXEMPTY PP_STAT_SEL /* Tx Empty, channel 0. 1 0 0 */ -// TXEMPTY1 PP_STAT_SEL /* Tx Empty, channel 1. 1 0 1 */ -// TXEMPTY2 PP_STAT_SEL /* Tx Empty, channel 2. 1 1 0 */ -// TXEMPTY3 PP_STAT_SEL /* Tx Empty, channel 3. 1 1 1 */ - -/* BUSY LINE: A3 A2 A1 - * -------- - */ -#define RXDATA PP_STAT_BSY /* Rx Input Data, channel 0. 0 0 0 */ -// RXDATA1 PP_STAT_BSY /* Rx Input Data, channel 1. 0 0 1 */ -#define SYNC_DATA PP_STAT_BSY /* Reserved - Sync Data. 0 1 0 */ - /* Reserved. 0 1 1 */ -#define DATA_ECHO PP_STAT_BSY /* Parallel Port Data Echo. 1 0 0 */ -#define A0_ECHO PP_STAT_BSY /* Address 0 Echo. 1 0 1 */ -#define A1_ECHO PP_STAT_BSY /* Address 1 Echo. 1 1 0 */ -#define A2_ECHO PP_STAT_BSY /* Address 2 Echo. 1 1 1 */ - -#define PORTMAN2X4_MODE_INPUT_TRIGGERED 0x01 - -/********************************************************************* - * Hardware specific functions - *********************************************************************/ -static inline void portman_write_command(struct portman *pm, u8 value) -{ - parport_write_control(pm->pardev->port, value); -} - -static inline u8 portman_read_command(struct portman *pm) -{ - return parport_read_control(pm->pardev->port); -} - -static inline u8 portman_read_status(struct portman *pm) -{ - return parport_read_status(pm->pardev->port); -} - -static inline u8 portman_read_data(struct portman *pm) -{ - return parport_read_data(pm->pardev->port); -} - -static inline void portman_write_data(struct portman *pm, u8 value) -{ - parport_write_data(pm->pardev->port, value); -} - -static void portman_write_midi(struct portman *pm, - int port, u8 mididata) -{ - int command = ((port + 4) << 1); - - /* Get entering data byte and port number in BL and BH respectively. - * Set up Tx Channel address field for use with PP Cmd Register. - * Store address field in BH register. - * Inputs: AH = Output port number (0..3). - * AL = Data byte. - * command = TXDATA0 | INT_EN; - * Align port num with address field (b1...b3), - * set address for TXDatax, Strobe=0 - */ - command |= INT_EN; - - /* Disable interrupts so that the process is not interrupted, then - * write the address associated with the current Tx channel to the - * PP Command Reg. Do not set the Strobe signal yet. - */ - - do { - portman_write_command(pm, command); - - /* While the address lines settle, write parallel output data to - * PP Data Reg. This has no effect until Strobe signal is asserted. - */ - - portman_write_data(pm, mididata); - - /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP - * Status Register), then go write data. Else go back and wait. - */ - } while ((portman_read_status(pm) & TXEMPTY) != TXEMPTY); - - /* TxEmpty is set. Maintain PC/P destination address and assert - * Strobe through the PP Command Reg. This will Strobe data into - * the PC/P transmitter and set the PC/P BUSY signal. - */ - - portman_write_command(pm, command | STROBE); - - /* Wait for strobe line to settle and echo back through hardware. - * Once it has echoed back, assume that the address and data lines - * have settled! - */ - - while ((portman_read_status(pm) & ESTB) == 0) - cpu_relax(); - - /* Release strobe and immediately re-allow interrupts. */ - portman_write_command(pm, command); - - while ((portman_read_status(pm) & ESTB) == ESTB) - cpu_relax(); - - /* PC/P BUSY is now set. We must wait until BUSY resets itself. - * We'll reenable ints while we're waiting. - */ - - while ((portman_read_status(pm) & BUSY) == BUSY) - cpu_relax(); - - /* Data sent. */ -} - - -/* - * Read MIDI byte from port - * Attempt to read input byte from specified hardware input port (0..). - * Return -1 if no data - */ -static int portman_read_midi(struct portman *pm, int port) -{ - unsigned char midi_data = 0; - unsigned char cmdout; /* Saved address+IE bit. */ - - /* Make sure clocking edge is down before starting... */ - portman_write_data(pm, 0); /* Make sure edge is down. */ - - /* Set destination address to PCP. */ - cmdout = (port << 1) | INT_EN; /* Address + IE + No Strobe. */ - portman_write_command(pm, cmdout); - - while ((portman_read_status(pm) & ESTB) == ESTB) - cpu_relax(); /* Wait for strobe echo. */ - - /* After the address lines settle, check multiplexed RxAvail signal. - * If data is available, read it. - */ - if ((portman_read_status(pm) & RXAVAIL) == 0) - return -1; /* No data. */ - - /* Set the Strobe signal to enable the Rx clocking circuitry. */ - portman_write_command(pm, cmdout | STROBE); /* Write address+IE+Strobe. */ - - while ((portman_read_status(pm) & ESTB) == 0) - cpu_relax(); /* Wait for strobe echo. */ - - /* The first data bit (msb) is already sitting on the input line. */ - midi_data = (portman_read_status(pm) & 128); - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 6. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 1) & 64; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 5. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 2) & 32; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 4. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 3) & 16; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 3. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 4) & 8; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 2. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 5) & 4; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 1. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 6) & 2; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - - /* Data bit 0. */ - portman_write_data(pm, 0); /* Cause falling edge while data settles. */ - midi_data |= (portman_read_status(pm) >> 7) & 1; - portman_write_data(pm, 1); /* Cause rising edge, which shifts data. */ - portman_write_data(pm, 0); /* Return data clock low. */ - - - /* De-assert Strobe and return data. */ - portman_write_command(pm, cmdout); /* Output saved address+IE. */ - - /* Wait for strobe echo. */ - while ((portman_read_status(pm) & ESTB) == ESTB) - cpu_relax(); - - return (midi_data & 255); /* Shift back and return value. */ -} - -/* - * Checks if any input data on the given channel is available - * Checks RxAvail - */ -static int portman_data_avail(struct portman *pm, int channel) -{ - int command = INT_EN; - switch (channel) { - case 0: - command |= RXDATA0; - break; - case 1: - command |= RXDATA1; - break; - } - /* Write hardware (assumme STROBE=0) */ - portman_write_command(pm, command); - /* Check multiplexed RxAvail signal */ - if ((portman_read_status(pm) & RXAVAIL) == RXAVAIL) - return 1; /* Data available */ - - /* No Data available */ - return 0; -} - - -/* - * Flushes any input - */ -static void portman_flush_input(struct portman *pm, unsigned char port) -{ - /* Local variable for counting things */ - unsigned int i = 0; - unsigned char command = 0; - - switch (port) { - case 0: - command = RXDATA0; - break; - case 1: - command = RXDATA1; - break; - default: - snd_printk(KERN_WARNING - "portman_flush_input() Won't flush port %i\n", - port); - return; - } - - /* Set address for specified channel in port and allow to settle. */ - portman_write_command(pm, command); - - /* Assert the Strobe and wait for echo back. */ - portman_write_command(pm, command | STROBE); - - /* Wait for ESTB */ - while ((portman_read_status(pm) & ESTB) == 0) - cpu_relax(); - - /* Output clock cycles to the Rx circuitry. */ - portman_write_data(pm, 0); - - /* Flush 250 bits... */ - for (i = 0; i < 250; i++) { - portman_write_data(pm, 1); - portman_write_data(pm, 0); - } - - /* Deassert the Strobe signal of the port and wait for it to settle. */ - portman_write_command(pm, command | INT_EN); - - /* Wait for settling */ - while ((portman_read_status(pm) & ESTB) == ESTB) - cpu_relax(); -} - -static int portman_probe(struct parport *p) -{ - /* Initialize the parallel port data register. Will set Rx clocks - * low in case we happen to be addressing the Rx ports at this time. - */ - /* 1 */ - parport_write_data(p, 0); - - /* Initialize the parallel port command register, thus initializing - * hardware handshake lines to midi box: - * - * Strobe = 0 - * Interrupt Enable = 0 - */ - /* 2 */ - parport_write_control(p, 0); - - /* Check if Portman PC/P 2x4 is out there. */ - /* 3 */ - parport_write_control(p, RXDATA0); /* Write Strobe=0 to command reg. */ - - /* Check for ESTB to be clear */ - /* 4 */ - if ((parport_read_status(p) & ESTB) == ESTB) - return 1; /* CODE 1 - Strobe Failure. */ - - /* Set for RXDATA0 where no damage will be done. */ - /* 5 */ - parport_write_control(p, RXDATA0 + STROBE); /* Write Strobe=1 to command reg. */ - - /* 6 */ - if ((parport_read_status(p) & ESTB) != ESTB) - return 1; /* CODE 1 - Strobe Failure. */ - - /* 7 */ - parport_write_control(p, 0); /* Reset Strobe=0. */ - - /* Check if Tx circuitry is functioning properly. If initialized - * unit TxEmpty is false, send out char and see if if goes true. - */ - /* 8 */ - parport_write_control(p, TXDATA0); /* Tx channel 0, strobe off. */ - - /* If PCP channel's TxEmpty is set (TxEmpty is read through the PP - * Status Register), then go write data. Else go back and wait. - */ - /* 9 */ - if ((parport_read_status(p) & TXEMPTY) == 0) - return 2; - - /* Return OK status. */ - return 0; -} - -static int portman_device_init(struct portman *pm) -{ - portman_flush_input(pm, 0); - portman_flush_input(pm, 1); - - return 0; -} - -/********************************************************************* - * Rawmidi - *********************************************************************/ -static int snd_portman_midi_open(struct snd_rawmidi_substream *substream) -{ - return 0; -} - -static int snd_portman_midi_close(struct snd_rawmidi_substream *substream) -{ - return 0; -} - -static void snd_portman_midi_input_trigger(struct snd_rawmidi_substream *substream, - int up) -{ - struct portman *pm = substream->rmidi->private_data; - unsigned long flags; - - spin_lock_irqsave(&pm->reg_lock, flags); - if (up) - pm->mode[substream->number] |= PORTMAN2X4_MODE_INPUT_TRIGGERED; - else - pm->mode[substream->number] &= ~PORTMAN2X4_MODE_INPUT_TRIGGERED; - spin_unlock_irqrestore(&pm->reg_lock, flags); -} - -static void snd_portman_midi_output_trigger(struct snd_rawmidi_substream *substream, - int up) -{ - struct portman *pm = substream->rmidi->private_data; - unsigned long flags; - unsigned char byte; - - spin_lock_irqsave(&pm->reg_lock, flags); - if (up) { - while ((snd_rawmidi_transmit(substream, &byte, 1) == 1)) - portman_write_midi(pm, substream->number, byte); - } - spin_unlock_irqrestore(&pm->reg_lock, flags); -} - -static struct snd_rawmidi_ops snd_portman_midi_output = { - .open = snd_portman_midi_open, - .close = snd_portman_midi_close, - .trigger = snd_portman_midi_output_trigger, -}; - -static struct snd_rawmidi_ops snd_portman_midi_input = { - .open = snd_portman_midi_open, - .close = snd_portman_midi_close, - .trigger = snd_portman_midi_input_trigger, -}; - -/* Create and initialize the rawmidi component */ -static int __devinit snd_portman_rawmidi_create(struct snd_card *card) -{ - struct portman *pm = card->private_data; - struct snd_rawmidi *rmidi; - struct snd_rawmidi_substream *substream; - int err; - - err = snd_rawmidi_new(card, CARD_NAME, 0, - PORTMAN_NUM_OUTPUT_PORTS, - PORTMAN_NUM_INPUT_PORTS, - &rmidi); - if (err < 0) - return err; - - rmidi->private_data = pm; - strcpy(rmidi->name, CARD_NAME); - rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | - SNDRV_RAWMIDI_INFO_INPUT | - SNDRV_RAWMIDI_INFO_DUPLEX; - - pm->rmidi = rmidi; - - /* register rawmidi ops */ - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, - &snd_portman_midi_output); - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, - &snd_portman_midi_input); - - /* name substreams */ - /* output */ - list_for_each_entry(substream, - &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams, - list) { - sprintf(substream->name, - "Portman2x4 %d", substream->number+1); - } - /* input */ - list_for_each_entry(substream, - &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams, - list) { - pm->midi_input[substream->number] = substream; - sprintf(substream->name, - "Portman2x4 %d", substream->number+1); - } - - return err; -} - -/********************************************************************* - * parport stuff - *********************************************************************/ -static void snd_portman_interrupt(int irq, void *userdata) -{ - unsigned char midivalue = 0; - struct portman *pm = ((struct snd_card*)userdata)->private_data; - - spin_lock(&pm->reg_lock); - - /* While any input data is waiting */ - while ((portman_read_status(pm) & INT_REQ) == INT_REQ) { - /* If data available on channel 0, - read it and stuff it into the queue. */ - if (portman_data_avail(pm, 0)) { - /* Read Midi */ - midivalue = portman_read_midi(pm, 0); - /* put midi into queue... */ - if (pm->mode[0] & PORTMAN2X4_MODE_INPUT_TRIGGERED) - snd_rawmidi_receive(pm->midi_input[0], - &midivalue, 1); - - } - /* If data available on channel 1, - read it and stuff it into the queue. */ - if (portman_data_avail(pm, 1)) { - /* Read Midi */ - midivalue = portman_read_midi(pm, 1); - /* put midi into queue... */ - if (pm->mode[1] & PORTMAN2X4_MODE_INPUT_TRIGGERED) - snd_rawmidi_receive(pm->midi_input[1], - &midivalue, 1); - } - - } - - spin_unlock(&pm->reg_lock); -} - -static int __devinit snd_portman_probe_port(struct parport *p) -{ - struct pardevice *pardev; - int res; - - pardev = parport_register_device(p, DRIVER_NAME, - NULL, NULL, NULL, - 0, NULL); - if (!pardev) - return -EIO; - - if (parport_claim(pardev)) { - parport_unregister_device(pardev); - return -EIO; - } - - res = portman_probe(p); - - parport_release(pardev); - parport_unregister_device(pardev); - - return res; -} - -static void __devinit snd_portman_attach(struct parport *p) -{ - struct platform_device *device; - - device = platform_device_alloc(PLATFORM_DRIVER, device_count); - if (!device) - return; - - /* Temporary assignment to forward the parport */ - platform_set_drvdata(device, p); - - if (platform_device_register(device) < 0) { - platform_device_put(device); - return; - } - - /* Since we dont get the return value of probe - * We need to check if device probing succeeded or not */ - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - return; - } - - /* register device in global table */ - platform_devices[device_count] = device; - device_count++; -} - -static void snd_portman_detach(struct parport *p) -{ - /* nothing to do here */ -} - -static struct parport_driver portman_parport_driver = { - .name = "portman2x4", - .attach = snd_portman_attach, - .detach = snd_portman_detach -}; - -/********************************************************************* - * platform stuff - *********************************************************************/ -static void snd_portman_card_private_free(struct snd_card *card) -{ - struct portman *pm = card->private_data; - struct pardevice *pardev = pm->pardev; - - if (pardev) { - if (pm->pardev_claimed) - parport_release(pardev); - parport_unregister_device(pardev); - } - - portman_free(pm); -} - -static int __devinit snd_portman_probe(struct platform_device *pdev) -{ - struct pardevice *pardev; - struct parport *p; - int dev = pdev->id; - struct snd_card *card = NULL; - struct portman *pm = NULL; - int err; - - p = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) - return -ENOENT; - - if ((err = snd_portman_probe_port(p)) < 0) - return err; - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) { - snd_printd("Cannot create card\n"); - return -ENOMEM; - } - strcpy(card->driver, DRIVER_NAME); - strcpy(card->shortname, CARD_NAME); - sprintf(card->longname, "%s at 0x%lx, irq %i", - card->shortname, p->base, p->irq); - - pardev = parport_register_device(p, /* port */ - DRIVER_NAME, /* name */ - NULL, /* preempt */ - NULL, /* wakeup */ - snd_portman_interrupt, /* ISR */ - PARPORT_DEV_EXCL, /* flags */ - (void *)card); /* private */ - if (pardev == NULL) { - snd_printd("Cannot register pardevice\n"); - err = -EIO; - goto __err; - } - - if ((err = portman_create(card, pardev, &pm)) < 0) { - snd_printd("Cannot create main component\n"); - parport_unregister_device(pardev); - goto __err; - } - card->private_data = pm; - card->private_free = snd_portman_card_private_free; - - if ((err = snd_portman_rawmidi_create(card)) < 0) { - snd_printd("Creating Rawmidi component failed\n"); - goto __err; - } - - /* claim parport */ - if (parport_claim(pardev)) { - snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base); - err = -EIO; - goto __err; - } - pm->pardev_claimed = 1; - - /* init device */ - if ((err = portman_device_init(pm)) < 0) - goto __err; - - platform_set_drvdata(pdev, card); - - /* At this point card will be usable */ - if ((err = snd_card_register(card)) < 0) { - snd_printd("Cannot register card\n"); - goto __err; - } - - snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base); - return 0; - -__err: - snd_card_free(card); - return err; -} - -static int snd_portman_remove(struct platform_device *pdev) -{ - struct snd_card *card = platform_get_drvdata(pdev); - - if (card) - snd_card_free(card); - - return 0; -} - - -static struct platform_driver snd_portman_driver = { - .probe = snd_portman_probe, - .remove = snd_portman_remove, - .driver = { - .name = PLATFORM_DRIVER - } -}; - -/********************************************************************* - * module init stuff - *********************************************************************/ -static void snd_portman_unregister_all(void) -{ - int i; - - for (i = 0; i < SNDRV_CARDS; ++i) { - if (platform_devices[i]) { - platform_device_unregister(platform_devices[i]); - platform_devices[i] = NULL; - } - } - platform_driver_unregister(&snd_portman_driver); - parport_unregister_driver(&portman_parport_driver); -} - -static int __init snd_portman_module_init(void) -{ - int err; - - if ((err = platform_driver_register(&snd_portman_driver)) < 0) - return err; - - if (parport_register_driver(&portman_parport_driver) != 0) { - platform_driver_unregister(&snd_portman_driver); - return -EIO; - } - - if (device_count == 0) { - snd_portman_unregister_all(); - return -ENODEV; - } - - return 0; -} - -static void __exit snd_portman_module_exit(void) -{ - snd_portman_unregister_all(); -} - -module_init(snd_portman_module_init); -module_exit(snd_portman_module_exit); diff --git a/trunk/sound/drivers/serial-u16550.c b/trunk/sound/drivers/serial-u16550.c index 3a86a5820726..74028b2219c2 100644 --- a/trunk/sound/drivers/serial-u16550.c +++ b/trunk/sound/drivers/serial-u16550.c @@ -117,13 +117,13 @@ MODULE_PARM_DESC(adaptor, "Type of adaptor."); #define SERIAL_MODE_INPUT_TRIGGERED (1 << 2) #define SERIAL_MODE_OUTPUT_TRIGGERED (1 << 3) -struct snd_uart16550 { +typedef struct _snd_uart16550 { struct snd_card *card; struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS]; struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS]; - int filemode; /* open status of file */ + int filemode; //open status of file spinlock_t open_lock; @@ -140,39 +140,39 @@ struct snd_uart16550 { unsigned char old_divisor_msb; unsigned char old_line_ctrl_reg; - /* parameter for using of write loop */ - short int fifo_limit; /* used in uart16550 */ - short int fifo_count; /* used in uart16550 */ + // parameter for using of write loop + short int fifo_limit; //used in uart16550 + short int fifo_count; //used in uart16550 - /* type of adaptor */ + // type of adaptor int adaptor; - /* inputs */ + // inputs int prev_in; unsigned char rstatus; - /* outputs */ + // outputs int prev_out; unsigned char prev_status[SNDRV_SERIAL_MAX_OUTS]; - /* write buffer and its writing/reading position */ + // write buffer and its writing/reading position unsigned char tx_buff[TX_BUFF_SIZE]; int buff_in_count; int buff_in; int buff_out; int drop_on_full; - /* wait timer */ + // wait timer unsigned int timer_running:1; struct timer_list buffer_timer; -}; +} snd_uart16550_t; static struct platform_device *devices[SNDRV_CARDS]; -static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) +static inline void snd_uart16550_add_timer(snd_uart16550_t *uart) { - if (!uart->timer_running) { + if (! uart->timer_running) { /* timer 38600bps * 10bit * 16byte */ uart->buffer_timer.expires = jiffies + (HZ+255)/256; uart->timer_running = 1; @@ -180,7 +180,7 @@ static inline void snd_uart16550_add_timer(struct snd_uart16550 *uart) } } -static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart) +static inline void snd_uart16550_del_timer(snd_uart16550_t *uart) { if (uart->timer_running) { del_timer(&uart->buffer_timer); @@ -189,10 +189,10 @@ static inline void snd_uart16550_del_timer(struct snd_uart16550 *uart) } /* This macro is only used in snd_uart16550_io_loop */ -static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart) +static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart) { unsigned short buff_out = uart->buff_out; - if (uart->buff_in_count > 0) { + if( uart->buff_in_count > 0 ) { outb(uart->tx_buff[buff_out], uart->base + UART_TX); uart->fifo_count++; buff_out++; @@ -206,7 +206,7 @@ static inline void snd_uart16550_buffer_output(struct snd_uart16550 *uart) * We don't want to interrupt this, * as we're already handling an interrupt */ -static void snd_uart16550_io_loop(struct snd_uart16550 * uart) +static void snd_uart16550_io_loop(snd_uart16550_t * uart) { unsigned char c, status; int substream; @@ -220,8 +220,9 @@ static void snd_uart16550_io_loop(struct snd_uart16550 * uart) c = inb(uart->base + UART_RX); /* keep track of last status byte */ - if (c & 0x80) + if (c & 0x80) { uart->rstatus = c; + } /* handle stream switch */ if (uart->adaptor == SNDRV_SERIAL_GENERIC) { @@ -229,16 +230,14 @@ static void snd_uart16550_io_loop(struct snd_uart16550 * uart) if (c <= SNDRV_SERIAL_MAX_INS && c > 0) substream = c - 1; if (c != 0xf5) - /* prevent future bytes from being - interpreted as streams */ - uart->rstatus = 0; - } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) - && uart->midi_input[substream]) - snd_rawmidi_receive(uart->midi_input[substream], - &c, 1); - } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && - uart->midi_input[substream]) + uart->rstatus = 0; /* prevent future bytes from being interpreted as streams */ + } + else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { + snd_rawmidi_receive(uart->midi_input[substream], &c, 1); + } + } else if ((uart->filemode & SERIAL_MODE_INPUT_OPEN) && (uart->midi_input[substream] != NULL)) { snd_rawmidi_receive(uart->midi_input[substream], &c, 1); + } if (status & UART_LSR_OE) snd_printk("%s: Overrun on device at 0x%lx\n", @@ -251,20 +250,21 @@ static void snd_uart16550_io_loop(struct snd_uart16550 * uart) /* no need of check SERIAL_MODE_OUTPUT_OPEN because if not, buffer is never filled. */ /* Check write status */ - if (status & UART_LSR_THRE) + if (status & UART_LSR_THRE) { uart->fifo_count = 0; + } if (uart->adaptor == SNDRV_SERIAL_MS124W_SA || uart->adaptor == SNDRV_SERIAL_GENERIC) { /* Can't use FIFO, must send only when CTS is true */ status = inb(uart->base + UART_MSR); - while (uart->fifo_count == 0 && (status & UART_MSR_CTS) && - uart->buff_in_count > 0) { + while( (uart->fifo_count == 0) && (status & UART_MSR_CTS) && + (uart->buff_in_count > 0) ) { snd_uart16550_buffer_output(uart); - status = inb(uart->base + UART_MSR); + status = inb( uart->base + UART_MSR ); } } else { /* Write loop */ - while (uart->fifo_count < uart->fifo_limit /* Can we write ? */ + while (uart->fifo_count < uart->fifo_limit /* Can we write ? */ && uart->buff_in_count > 0) /* Do we want to? */ snd_uart16550_buffer_output(uart); } @@ -294,16 +294,15 @@ static void snd_uart16550_io_loop(struct snd_uart16550 * uart) */ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) { - struct snd_uart16550 *uart; + snd_uart16550_t *uart; - uart = dev_id; + uart = (snd_uart16550_t *) dev_id; spin_lock(&uart->open_lock); if (uart->filemode == SERIAL_MODE_NOT_OPENED) { spin_unlock(&uart->open_lock); return IRQ_NONE; } - /* indicate to the UART that the interrupt has been serviced */ - inb(uart->base + UART_IIR); + inb(uart->base + UART_IIR); /* indicate to the UART that the interrupt has been serviced */ snd_uart16550_io_loop(uart); spin_unlock(&uart->open_lock); return IRQ_HANDLED; @@ -313,9 +312,9 @@ static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id) static void snd_uart16550_buffer_timer(unsigned long data) { unsigned long flags; - struct snd_uart16550 *uart; + snd_uart16550_t *uart; - uart = (struct snd_uart16550 *)data; + uart = (snd_uart16550_t *)data; spin_lock_irqsave(&uart->open_lock, flags); snd_uart16550_del_timer(uart); snd_uart16550_io_loop(uart); @@ -327,7 +326,7 @@ static void snd_uart16550_buffer_timer(unsigned long data) * return 0 if found * return negative error if not found */ -static int __init snd_uart16550_detect(struct snd_uart16550 *uart) +static int __init snd_uart16550_detect(snd_uart16550_t *uart) { unsigned long io_base = uart->base; int ok; @@ -344,8 +343,7 @@ static int __init snd_uart16550_detect(struct snd_uart16550 *uart) return -EBUSY; } - /* uart detected unless one of the following tests should fail */ - ok = 1; + ok = 1; /* uart detected unless one of the following tests should fail */ /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */ outb(UART_LCR_WLEN8, io_base + UART_LCR); /* Line Control Register */ c = inb(io_base + UART_IER); @@ -370,7 +368,7 @@ static int __init snd_uart16550_detect(struct snd_uart16550 *uart) return ok; } -static void snd_uart16550_do_open(struct snd_uart16550 * uart) +static void snd_uart16550_do_open(snd_uart16550_t * uart) { char byte; @@ -462,7 +460,7 @@ static void snd_uart16550_do_open(struct snd_uart16550 * uart) inb(uart->base + UART_RX); /* Clear any pre-existing receive interrupt */ } -static void snd_uart16550_do_close(struct snd_uart16550 * uart) +static void snd_uart16550_do_close(snd_uart16550_t * uart) { if (uart->irq < 0) snd_uart16550_del_timer(uart); @@ -516,7 +514,7 @@ static void snd_uart16550_do_close(struct snd_uart16550 * uart) static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) @@ -530,7 +528,7 @@ static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_INPUT_OPEN; @@ -541,24 +539,24 @@ static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream) return 0; } -static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, - int up) +static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); - if (up) + if (up) { uart->filemode |= SERIAL_MODE_INPUT_TRIGGERED; - else + } else { uart->filemode &= ~SERIAL_MODE_INPUT_TRIGGERED; + } spin_unlock_irqrestore(&uart->open_lock, flags); } static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); if (uart->filemode == SERIAL_MODE_NOT_OPENED) @@ -572,7 +570,7 @@ static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream) static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); uart->filemode &= ~SERIAL_MODE_OUTPUT_OPEN; @@ -583,20 +581,18 @@ static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream) return 0; }; -static inline int snd_uart16550_buffer_can_write(struct snd_uart16550 *uart, - int Num) +static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num ) { - if (uart->buff_in_count + Num < TX_BUFF_SIZE) + if( uart->buff_in_count + Num < TX_BUFF_SIZE ) return 1; else return 0; } -static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart, - unsigned char byte) +static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte) { unsigned short buff_in = uart->buff_in; - if (uart->buff_in_count < TX_BUFF_SIZE) { + if( uart->buff_in_count < TX_BUFF_SIZE ) { uart->tx_buff[buff_in] = byte; buff_in++; buff_in &= TX_BUFF_MASK; @@ -609,14 +605,12 @@ static inline int snd_uart16550_write_buffer(struct snd_uart16550 *uart, return 0; } -static int snd_uart16550_output_byte(struct snd_uart16550 *uart, - struct snd_rawmidi_substream *substream, - unsigned char midi_byte) +static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte) { - if (uart->buff_in_count == 0 /* Buffer empty? */ + if (uart->buff_in_count == 0 /* Buffer empty? */ && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA && uart->adaptor != SNDRV_SERIAL_GENERIC) || - (uart->fifo_count == 0 /* FIFO empty? */ + (uart->fifo_count == 0 /* FIFO empty? */ && (inb(uart->base + UART_MSR) & UART_MSR_CTS)))) { /* CTS? */ /* Tx Buffer Empty - try to write immediately */ @@ -629,13 +623,12 @@ static int snd_uart16550_output_byte(struct snd_uart16550 *uart, uart->fifo_count++; outb(midi_byte, uart->base + UART_TX); } else { - /* Cannot write (buffer empty) - - * put char in buffer */ + /* Cannot write (buffer empty) - put char in buffer */ snd_uart16550_write_buffer(uart, midi_byte); } } } else { - if (!snd_uart16550_write_buffer(uart, midi_byte)) { + if( !snd_uart16550_write_buffer(uart, midi_byte) ) { snd_printk("%s: Buffer overrun on device at 0x%lx\n", uart->rmidi->name, uart->base); return 0; @@ -649,9 +642,9 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) { unsigned long flags; unsigned char midi_byte, addr_byte; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; char first; - static unsigned long lasttime = 0; + static unsigned long lasttime=0; /* Interupts are disabled during the updating of the tx_buff, * since it is 'bad' to have two processes updating the same @@ -660,7 +653,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_lock_irqsave(&uart->open_lock, flags); - if (uart->irq < 0) /* polling */ + if (uart->irq < 0) //polling snd_uart16550_io_loop(uart); if (uart->adaptor == SNDRV_SERIAL_MS124W_MB) { @@ -678,8 +671,7 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) /* select any combination of the four ports */ addr_byte = (substream->number << 4) | 0x08; /* ...except none */ - if (addr_byte == 0x08) - addr_byte = 0xf8; + if (addr_byte == 0x08) addr_byte = 0xf8; #endif snd_uart16550_output_byte(uart, substream, addr_byte); /* send midi byte */ @@ -687,42 +679,31 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) } } else { first = 0; - while (snd_rawmidi_transmit_peek(substream, &midi_byte, 1) == 1) { - /* Also send F5 after 3 seconds with no data - * to handle device disconnect */ - if (first == 0 && - (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || - uart->adaptor == SNDRV_SERIAL_GENERIC) && - (uart->prev_out != substream->number || - jiffies-lasttime > 3*HZ)) { - - if (snd_uart16550_buffer_can_write(uart, 3)) { + while( 1 == snd_rawmidi_transmit_peek(substream, &midi_byte, 1) ) { + /* Also send F5 after 3 seconds with no data to handle device disconnect */ + if (first == 0 && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS || + uart->adaptor == SNDRV_SERIAL_GENERIC) && + (uart->prev_out != substream->number || jiffies-lasttime > 3*HZ)) { + + if( snd_uart16550_buffer_can_write( uart, 3 ) ) { /* Roland Soundcanvas part selection */ - /* If this substream of the data is - * different previous substream - * in this uart, send the change part - * event - */ + /* If this substream of the data is different previous + substream in this uart, send the change part event */ uart->prev_out = substream->number; /* change part */ - snd_uart16550_output_byte(uart, substream, - 0xf5); + snd_uart16550_output_byte(uart, substream, 0xf5); /* data */ - snd_uart16550_output_byte(uart, substream, - uart->prev_out + 1); - /* If midi_byte is a data byte, - * send the previous status byte */ - if (midi_byte < 0x80 && - uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS) + snd_uart16550_output_byte(uart, substream, uart->prev_out + 1); + /* If midi_byte is a data byte, send the previous status byte */ + if ((midi_byte < 0x80) && (uart->adaptor == SNDRV_SERIAL_SOUNDCANVAS)) snd_uart16550_output_byte(uart, substream, uart->prev_status[uart->prev_out]); - } else if (!uart->drop_on_full) + } else if( !uart->drop_on_full ) break; } /* send midi byte */ - if (!snd_uart16550_output_byte(uart, substream, midi_byte) && - !uart->drop_on_full ) + if( !snd_uart16550_output_byte(uart, substream, midi_byte) && !uart->drop_on_full ) break; if (midi_byte >= 0x80 && midi_byte < 0xf0) @@ -736,17 +717,17 @@ static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream) spin_unlock_irqrestore(&uart->open_lock, flags); } -static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, - int up) +static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up) { unsigned long flags; - struct snd_uart16550 *uart = substream->rmidi->private_data; + snd_uart16550_t *uart = substream->rmidi->private_data; spin_lock_irqsave(&uart->open_lock, flags); - if (up) + if (up) { uart->filemode |= SERIAL_MODE_OUTPUT_TRIGGERED; - else + } else { uart->filemode &= ~SERIAL_MODE_OUTPUT_TRIGGERED; + } spin_unlock_irqrestore(&uart->open_lock, flags); if (up) snd_uart16550_output_write(substream); @@ -766,10 +747,10 @@ static struct snd_rawmidi_ops snd_uart16550_input = .trigger = snd_uart16550_input_trigger, }; -static int snd_uart16550_free(struct snd_uart16550 *uart) +static int snd_uart16550_free(snd_uart16550_t *uart) { if (uart->irq >= 0) - free_irq(uart->irq, uart); + free_irq(uart->irq, (void *)uart); release_and_free_resource(uart->res_base); kfree(uart); return 0; @@ -777,7 +758,7 @@ static int snd_uart16550_free(struct snd_uart16550 *uart) static int snd_uart16550_dev_free(struct snd_device *device) { - struct snd_uart16550 *uart = device->device_data; + snd_uart16550_t *uart = device->device_data; return snd_uart16550_free(uart); } @@ -788,12 +769,12 @@ static int __init snd_uart16550_create(struct snd_card *card, unsigned int base, int adaptor, int droponfull, - struct snd_uart16550 **ruart) + snd_uart16550_t **ruart) { static struct snd_device_ops ops = { .dev_free = snd_uart16550_dev_free, }; - struct snd_uart16550 *uart; + snd_uart16550_t *uart; int err; @@ -814,7 +795,7 @@ static int __init snd_uart16550_create(struct snd_card *card, if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { if (request_irq(irq, snd_uart16550_interrupt, - IRQF_DISABLED, "Serial MIDI", uart)) { + IRQF_DISABLED, "Serial MIDI", (void *) uart)) { snd_printk("irq %d busy. Using Polling.\n", irq); } else { uart->irq = irq; @@ -862,28 +843,23 @@ static int __init snd_uart16550_create(struct snd_card *card, static void __init snd_uart16550_substreams(struct snd_rawmidi_str *stream) { - struct snd_rawmidi_substream *substream; + struct list_head *list; - list_for_each_entry(substream, &stream->substreams, list) { + list_for_each(list, &stream->substreams) { + struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list); sprintf(substream->name, "Serial MIDI %d", substream->number + 1); } } -static int __init snd_uart16550_rmidi(struct snd_uart16550 *uart, int device, - int outs, int ins, - struct snd_rawmidi **rmidi) +static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi) { struct snd_rawmidi *rrawmidi; int err; - err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, - outs, ins, &rrawmidi); - if (err < 0) + if ((err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi)) < 0) return err; - snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, - &snd_uart16550_input); - snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, - &snd_uart16550_output); + snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_uart16550_input); + snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_uart16550_output); strcpy(rrawmidi->name, "Serial MIDI"); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]); snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]); @@ -899,7 +875,7 @@ static int __init snd_uart16550_rmidi(struct snd_uart16550 *uart, int device, static int __init snd_serial_probe(struct platform_device *devptr) { struct snd_card *card; - struct snd_uart16550 *uart; + snd_uart16550_t *uart; int err; int dev = devptr->id; @@ -953,8 +929,7 @@ static int __init snd_serial_probe(struct platform_device *devptr) &uart)) < 0) goto _err; - err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi); - if (err < 0) + if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0) goto _err; sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d", diff --git a/trunk/sound/drivers/vx/vx_mixer.c b/trunk/sound/drivers/vx/vx_mixer.c index f63152a6a223..1613ed844ac6 100644 --- a/trunk/sound/drivers/vx/vx_mixer.c +++ b/trunk/sound/drivers/vx/vx_mixer.c @@ -716,7 +716,7 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return 0; } -static const DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0); +static DECLARE_TLV_DB_SCALE(db_scale_audio_gain, -10975, 25, 0); static struct snd_kcontrol_new vx_control_audio_gain = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, diff --git a/trunk/sound/i2c/Makefile b/trunk/sound/i2c/Makefile index 45902d48c89c..816a2e7c88ca 100644 --- a/trunk/sound/i2c/Makefile +++ b/trunk/sound/i2c/Makefile @@ -16,4 +16,3 @@ obj-$(CONFIG_SND) += other/ # Toplevel Module Dependency obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o -obj-$(CONFIG_SND_ICE1724) += snd-i2c.o diff --git a/trunk/sound/i2c/other/Makefile b/trunk/sound/i2c/other/Makefile index 77a8a7c75dd9..2fe023ef00a7 100644 --- a/trunk/sound/i2c/other/Makefile +++ b/trunk/sound/i2c/other/Makefile @@ -6,11 +6,11 @@ snd-ak4114-objs := ak4114.o snd-ak4117-objs := ak4117.o snd-ak4xxx-adda-objs := ak4xxx-adda.o -snd-pt2258-objs := pt2258.o snd-tea575x-tuner-objs := tea575x-tuner.o # Module Dependency obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o -obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4xxx-adda.o snd-pt2258.o +obj-$(CONFIG_SND_ICE1724) += snd-ak4xxx-adda.o +obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index adbfd5884d06..d2f2c5078e65 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -42,8 +42,8 @@ static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char va ak4114->write(ak4114->private_data, reg, val); if (reg <= AK4114_REG_INT1_MASK) ak4114->regmap[reg] = val; - else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4) - ak4114->txcsb[reg-AK4114_REG_TXCSB0] = val; + else if (reg >= AK4114_REG_RXCSB0 && reg <= AK4114_REG_TXCSB4) + ak4114->txcsb[reg-AK4114_REG_RXCSB0] = val; } static inline unsigned char reg_read(struct ak4114 *ak4114, unsigned char reg) @@ -66,8 +66,10 @@ static void snd_ak4114_free(struct ak4114 *chip) { chip->init = 1; /* don't schedule new work */ mb(); - cancel_delayed_work(&chip->work); - flush_scheduled_work(); + if (chip->workqueue != NULL) { + flush_workqueue(chip->workqueue); + destroy_workqueue(chip->workqueue); + } kfree(chip); } @@ -80,7 +82,7 @@ static int snd_ak4114_dev_free(struct snd_device *device) int snd_ak4114_create(struct snd_card *card, ak4114_read_t *read, ak4114_write_t *write, - const unsigned char pgm[7], const unsigned char txcsb[5], + unsigned char pgm[7], unsigned char txcsb[5], void *private_data, struct ak4114 **r_ak4114) { struct ak4114 *chip; @@ -98,13 +100,18 @@ int snd_ak4114_create(struct snd_card *card, chip->read = read; chip->write = write; chip->private_data = private_data; - INIT_DELAYED_WORK(&chip->work, ak4114_stats); for (reg = 0; reg < 7; reg++) chip->regmap[reg] = pgm[reg]; for (reg = 0; reg < 5; reg++) chip->txcsb[reg] = txcsb[reg]; + chip->workqueue = create_workqueue("snd-ak4114"); + if (chip->workqueue == NULL) { + kfree(chip); + return -ENOMEM; + } + snd_ak4114_reinit(chip); chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); @@ -127,8 +134,7 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char if (reg <= AK4114_REG_INT1_MASK) reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val); else if (reg >= AK4114_REG_TXCSB0 && reg <= AK4114_REG_TXCSB4) - reg_write(chip, reg, - (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); + reg_write(chip, reg, (chip->txcsb[reg] & ~mask) | val); } void snd_ak4114_reinit(struct ak4114 *chip) @@ -137,7 +143,7 @@ void snd_ak4114_reinit(struct ak4114 *chip) chip->init = 1; mb(); - flush_scheduled_work(); + flush_workqueue(chip->workqueue); /* bring the chip to reset state and powerdown state */ reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); udelay(200); @@ -152,7 +158,8 @@ void snd_ak4114_reinit(struct ak4114 *chip) reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); /* bring up statistics / event queing */ chip->init = 0; - schedule_delayed_work(&chip->work, HZ / 10); + INIT_DELAYED_WORK(&chip->work, ak4114_stats); + queue_delayed_work(chip->workqueue, &chip->work, HZ / 10); } static unsigned int external_rate(unsigned char rcs1) @@ -561,7 +568,7 @@ static void ak4114_stats(struct work_struct *work) if (chip->init) return; snd_ak4114_check_rate_and_errors(chip, 0); - schedule_delayed_work(&chip->work, HZ / 10); + queue_delayed_work(chip->workqueue, &chip->work, HZ / 10); } EXPORT_SYMBOL(snd_ak4114_create); diff --git a/trunk/sound/i2c/other/ak4117.c b/trunk/sound/i2c/other/ak4117.c index c022f29da2f7..4e45952dd95a 100644 --- a/trunk/sound/i2c/other/ak4117.c +++ b/trunk/sound/i2c/other/ak4117.c @@ -74,7 +74,7 @@ static int snd_ak4117_dev_free(struct snd_device *device) } int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write, - const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117) + unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117) { struct ak4117 *chip; int err = 0; diff --git a/trunk/sound/i2c/other/ak4xxx-adda.c b/trunk/sound/i2c/other/ak4xxx-adda.c index 8805110017a7..5da49e2eb350 100644 --- a/trunk/sound/i2c/other/ak4xxx-adda.c +++ b/trunk/sound/i2c/other/ak4xxx-adda.c @@ -140,7 +140,7 @@ EXPORT_SYMBOL(snd_akm4xxx_reset); * Used for AK4524 input/ouput attenuation, AK4528, and * AK5365 input attenuation */ -static const unsigned char vol_cvt_datt[128] = { +static unsigned char vol_cvt_datt[128] = { 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x0a, @@ -162,17 +162,17 @@ static const unsigned char vol_cvt_datt[128] = { /* * dB tables */ -static const DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1); -static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1); -static const DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0); +static DECLARE_TLV_DB_SCALE(db_scale_vol_datt, -6350, 50, 1); +static DECLARE_TLV_DB_SCALE(db_scale_8bit, -12750, 50, 1); +static DECLARE_TLV_DB_SCALE(db_scale_7bit, -6350, 50, 1); +static DECLARE_TLV_DB_LINEAR(db_scale_linear, TLV_DB_GAIN_MUTE, 0); /* * initialize all the ak4xxx chips */ void snd_akm4xxx_init(struct snd_akm4xxx *ak) { - static const unsigned char inits_ak4524[] = { + static unsigned char inits_ak4524[] = { 0x00, 0x07, /* 0: all power up */ 0x01, 0x00, /* 1: ADC/DAC reset */ 0x02, 0x60, /* 2: 24bit I2S */ @@ -184,7 +184,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) 0x07, 0x00, /* 7: DAC right muted */ 0xff, 0xff }; - static const unsigned char inits_ak4528[] = { + static unsigned char inits_ak4528[] = { 0x00, 0x07, /* 0: all power up */ 0x01, 0x00, /* 1: ADC/DAC reset */ 0x02, 0x60, /* 2: 24bit I2S */ @@ -194,7 +194,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) 0x05, 0x00, /* 5: ADC right muted */ 0xff, 0xff }; - static const unsigned char inits_ak4529[] = { + static unsigned char inits_ak4529[] = { 0x09, 0x01, /* 9: ATS=0, RSTN=1 */ 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */ 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */ @@ -210,7 +210,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) 0x08, 0x55, /* 8: deemphasis all off */ 0xff, 0xff }; - static const unsigned char inits_ak4355[] = { + static unsigned char inits_ak4355[] = { 0x01, 0x02, /* 1: reset and soft-mute */ 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, * disable DZF, sharp roll-off, RSTN#=0 */ @@ -227,7 +227,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) 0x01, 0x01, /* 1: un-reset, unmute */ 0xff, 0xff }; - static const unsigned char inits_ak4358[] = { + static unsigned char inits_ak4358[] = { 0x01, 0x02, /* 1: reset and soft-mute */ 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, * disable DZF, sharp roll-off, RSTN#=0 */ @@ -246,7 +246,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) 0x01, 0x01, /* 1: un-reset, unmute */ 0xff, 0xff }; - static const unsigned char inits_ak4381[] = { + static unsigned char inits_ak4381[] = { 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */ 0x01, 0x02, /* 1: de-emphasis off, normal speed, * sharp roll-off, DZF off */ @@ -259,8 +259,7 @@ void snd_akm4xxx_init(struct snd_akm4xxx *ak) }; int chip, num_chips; - const unsigned char *ptr, *inits; - unsigned char reg, data; + unsigned char *ptr, reg, data, *inits; memset(ak->images, 0, sizeof(ak->images)); memset(ak->volumes, 0, sizeof(ak->volumes)); @@ -514,66 +513,6 @@ static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol, return change; } -#define AK5365_NUM_INPUTS 5 - -static int ak4xxx_capture_source_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); - int mixer_ch = AK_GET_SHIFT(kcontrol->private_value); - const char **input_names; - int num_names, idx; - - input_names = ak->adc_info[mixer_ch].input_names; - - num_names = 0; - while (num_names < AK5365_NUM_INPUTS && input_names[num_names]) - ++num_names; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = num_names; - idx = uinfo->value.enumerated.item; - if (idx >= num_names) - return -EINVAL; - strncpy(uinfo->value.enumerated.name, input_names[idx], - sizeof(uinfo->value.enumerated.name)); - return 0; -} - -static int ak4xxx_capture_source_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); - int chip = AK_GET_CHIP(kcontrol->private_value); - int addr = AK_GET_ADDR(kcontrol->private_value); - int mask = AK_GET_MASK(kcontrol->private_value); - unsigned char val; - - val = snd_akm4xxx_get(ak, chip, addr) & mask; - ucontrol->value.enumerated.item[0] = val; - return 0; -} - -static int ak4xxx_capture_source_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); - int chip = AK_GET_CHIP(kcontrol->private_value); - int addr = AK_GET_ADDR(kcontrol->private_value); - int mask = AK_GET_MASK(kcontrol->private_value); - unsigned char oval, val; - - oval = snd_akm4xxx_get(ak, chip, addr); - val = oval & ~mask; - val |= ucontrol->value.enumerated.item[0] & mask; - if (val != oval) { - snd_akm4xxx_write(ak, chip, addr, val); - return 1; - } - return 0; -} - /* * build AK4xxx controls */ @@ -708,10 +647,9 @@ static int build_adc_controls(struct snd_akm4xxx *ak) if (ak->type == SND_AK5365 && (idx % 2) == 0) { if (! ak->adc_info || - ! ak->adc_info[mixer_ch].switch_name) { + ! ak->adc_info[mixer_ch].switch_name) knew.name = "Capture Switch"; - knew.index = mixer_ch + ak->idx_offset * 2; - } else + else knew.name = ak->adc_info[mixer_ch].switch_name; knew.info = ak4xxx_switch_info; knew.get = ak4xxx_switch_get; @@ -724,26 +662,6 @@ static int build_adc_controls(struct snd_akm4xxx *ak) err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); if (err < 0) return err; - - memset(&knew, 0, sizeof(knew)); - knew.name = ak->adc_info[mixer_ch].selector_name; - if (!knew.name) { - knew.name = "Capture Channel"; - knew.index = mixer_ch + ak->idx_offset * 2; - } - - knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - knew.info = ak4xxx_capture_source_info; - knew.get = ak4xxx_capture_source_get; - knew.put = ak4xxx_capture_source_put; - knew.access = 0; - /* input selector control: reg. 1, bits 0-2. - * mis-use 'shift' to pass mixer_ch */ - knew.private_value - = AK_COMPOSE(idx/2, 1, mixer_ch, 0x07); - err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); - if (err < 0) - return err; } idx += num_stereo; diff --git a/trunk/sound/i2c/other/pt2258.c b/trunk/sound/i2c/other/pt2258.c deleted file mode 100644 index e91cc3b44de5..000000000000 --- a/trunk/sound/i2c/other/pt2258.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * ALSA Driver for the PT2258 volume controller. - * - * Copyright (c) 2006 Jochen Voss - * - * 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 -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Jochen Voss "); -MODULE_DESCRIPTION("PT2258 volume controller (Princeton Technology Corp.)"); -MODULE_LICENSE("GPL"); - -#define PT2258_CMD_RESET 0xc0 -#define PT2258_CMD_UNMUTE 0xf8 -#define PT2258_CMD_MUTE 0xf9 - -static const unsigned char pt2258_channel_code[12] = { - 0x80, 0x90, /* channel 1: -10dB, -1dB */ - 0x40, 0x50, /* channel 2: -10dB, -1dB */ - 0x00, 0x10, /* channel 3: -10dB, -1dB */ - 0x20, 0x30, /* channel 4: -10dB, -1dB */ - 0x60, 0x70, /* channel 5: -10dB, -1dB */ - 0xa0, 0xb0 /* channel 6: -10dB, -1dB */ -}; - -int snd_pt2258_reset(struct snd_pt2258 *pt) -{ - unsigned char bytes[2]; - int i; - - /* reset chip */ - bytes[0] = PT2258_CMD_RESET; - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - /* mute all channels */ - pt->mute = 1; - bytes[0] = PT2258_CMD_MUTE; - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - /* set all channels to 0dB */ - for (i = 0; i < 6; ++i) - pt->volume[i] = 0; - bytes[0] = 0xd0; - bytes[1] = 0xe0; - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - return 0; - - __error: - snd_i2c_unlock(pt->i2c_bus); - snd_printk(KERN_ERR "PT2258 reset failed\n"); - return -EIO; -} - -static int pt2258_stereo_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 79; - return 0; -} - -static int pt2258_stereo_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_pt2258 *pt = kcontrol->private_data; - int base = kcontrol->private_value; - - /* chip does not support register reads */ - ucontrol->value.integer.value[0] = 79 - pt->volume[base]; - ucontrol->value.integer.value[1] = 79 - pt->volume[base + 1]; - return 0; -} - -static int pt2258_stereo_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_pt2258 *pt = kcontrol->private_data; - int base = kcontrol->private_value; - unsigned char bytes[2]; - int val0, val1; - - val0 = 79 - ucontrol->value.integer.value[0]; - val1 = 79 - ucontrol->value.integer.value[1]; - if (val0 == pt->volume[base] && val1 == pt->volume[base + 1]) - return 0; - - pt->volume[base] = val0; - bytes[0] = pt2258_channel_code[2 * base] | (val0 / 10); - bytes[1] = pt2258_channel_code[2 * base + 1] | (val0 % 10); - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - pt->volume[base + 1] = val1; - bytes[0] = pt2258_channel_code[2 * base + 2] | (val1 / 10); - bytes[1] = pt2258_channel_code[2 * base + 3] | (val1 % 10); - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - return 1; - - __error: - snd_i2c_unlock(pt->i2c_bus); - snd_printk(KERN_ERR "PT2258 access failed\n"); - return -EIO; -} - -static int pt2258_switch_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 pt2258_switch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_pt2258 *pt = kcontrol->private_data; - - ucontrol->value.integer.value[0] = !pt->mute; - return 0; -} - -static int pt2258_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_pt2258 *pt = kcontrol->private_data; - unsigned char bytes[2]; - int val; - - val = !ucontrol->value.integer.value[0]; - if (pt->mute == val) - return 0; - - pt->mute = val; - bytes[0] = val ? PT2258_CMD_MUTE : PT2258_CMD_UNMUTE; - snd_i2c_lock(pt->i2c_bus); - if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) - goto __error; - snd_i2c_unlock(pt->i2c_bus); - - return 1; - - __error: - snd_i2c_unlock(pt->i2c_bus); - snd_printk(KERN_ERR "PT2258 access failed 2\n"); - return -EIO; -} - -static const DECLARE_TLV_DB_SCALE(pt2258_db_scale, -7900, 100, 0); - -int snd_pt2258_build_controls(struct snd_pt2258 *pt) -{ - struct snd_kcontrol_new knew; - char *names[3] = { - "Mic Loopback Playback Volume", - "Line Loopback Playback Volume", - "CD Loopback Playback Volume" - }; - int i, err; - - for (i = 0; i < 3; ++i) { - memset(&knew, 0, sizeof(knew)); - knew.name = names[i]; - knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - knew.count = 1; - knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ; - knew.private_value = 2 * i; - knew.info = pt2258_stereo_volume_info; - knew.get = pt2258_stereo_volume_get; - knew.put = pt2258_stereo_volume_put; - knew.tlv.p = pt2258_db_scale; - - err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt)); - if (err < 0) - return err; - } - - memset(&knew, 0, sizeof(knew)); - knew.name = "Loopback Switch"; - knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - knew.info = pt2258_switch_info; - knew.get = pt2258_switch_get; - knew.put = pt2258_switch_put; - knew.access = 0; - err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt)); - if (err < 0) - return err; - - return 0; -} - -EXPORT_SYMBOL(snd_pt2258_reset); -EXPORT_SYMBOL(snd_pt2258_build_controls); diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index 4e3a9729f569..57371f1a441f 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -358,7 +358,6 @@ 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 help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and @@ -391,7 +390,6 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND - select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB diff --git a/trunk/sound/isa/ad1816a/ad1816a_lib.c b/trunk/sound/isa/ad1816a/ad1816a_lib.c index ec9209cd5177..b524e0d9ee44 100644 --- a/trunk/sound/isa/ad1816a/ad1816a_lib.c +++ b/trunk/sound/isa/ad1816a/ad1816a_lib.c @@ -906,11 +906,11 @@ static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = { AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1), diff --git a/trunk/sound/isa/ad1848/ad1848_lib.c b/trunk/sound/isa/ad1848/ad1848_lib.c index 8094282c2ae1..666b3bcc19f0 100644 --- a/trunk/sound/isa/ad1848/ad1848_lib.c +++ b/trunk/sound/isa/ad1848/ad1848_lib.c @@ -1223,9 +1223,9 @@ int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, EXPORT_SYMBOL(snd_ad1848_add_ctl_elem); -static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); static struct ad1848_mix_elem snd_ad1848_controls[] = { AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), diff --git a/trunk/sound/isa/gus/gus_main.c b/trunk/sound/isa/gus/gus_main.c index 8ced5e81b9a7..b680fddf0d74 100644 --- a/trunk/sound/isa/gus/gus_main.c +++ b/trunk/sound/isa/gus/gus_main.c @@ -294,10 +294,10 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) gus->mix_cntrl_reg |= 4; /* enable MIC */ } dma1 = gus->gf1.dma1; - dma1 = abs(dma1); + dma1 = dma1 < 0 ? -dma1 : dma1; dma1 = dmas[dma1 & 7]; dma2 = gus->gf1.dma2; - dma2 = abs(dma2); + dma2 = dma2 < 0 ? -dma2 : dma2; dma2 = dmas[dma2 & 7]; dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3); @@ -306,7 +306,7 @@ static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches) return -EINVAL; } irq = gus->gf1.irq; - irq = abs(irq); + irq = irq < 0 ? -irq : irq; irq = irqs[irq & 0x0f]; if (irq == 0) { snd_printk(KERN_ERR "Error! IRQ isn't defined.\n"); diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index 1e30713d2cad..419b4ebbf00e 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -486,8 +486,8 @@ static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_master, -3000, 200, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_master, -3000, 200, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); static struct snd_kcontrol_new snd_opl3sa2_controls[] = { OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1), diff --git a/trunk/sound/isa/sb/sb16_csp.c b/trunk/sound/isa/sb/sb16_csp.c index 3d9d7e0107ca..fcd638090a9e 100644 --- a/trunk/sound/isa/sb/sb16_csp.c +++ b/trunk/sound/isa/sb/sb16_csp.c @@ -161,13 +161,10 @@ 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) { - int i; struct snd_sb_csp *p = hwdep->private_data; if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); - for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) - release_firmware(p->csp_programs[i]); kfree(p); } } @@ -690,50 +687,8 @@ 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 #include "sb16_csp_codecs.h" -static const struct firmware snd_sb_csp_static_programs[] = { - { .data = mulaw_main, .size = sizeof mulaw_main }, - { .data = alaw_main, .size = sizeof alaw_main }, - { .data = ima_adpcm_init, .size = sizeof ima_adpcm_init }, - { .data = ima_adpcm_playback, .size = sizeof ima_adpcm_playback }, - { .data = ima_adpcm_capture, .size = sizeof ima_adpcm_capture }, -}; -#endif - -static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) -{ - static const char *const names[] = { - "sb16/mulaw_main.csp", - "sb16/alaw_main.csp", - "sb16/ima_adpcm_init.csp", - "sb16/ima_adpcm_playback.csp", - "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]; -#else - return err; -#endif - } - } - return snd_sb_csp_load(p, program->data, program->size, flags); -} - /* * autoload hardware codec if necessary * return 0 if CSP is loaded and ready to run (p->running != 0) @@ -753,27 +708,27 @@ static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec } else { switch (pcm_sfmt) { case SNDRV_PCM_FORMAT_MU_LAW: - err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0); + err = snd_sb_csp_load(p, &mulaw_main[0], sizeof(mulaw_main), 0); p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW; p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; break; case SNDRV_PCM_FORMAT_A_LAW: - err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0); + err = snd_sb_csp_load(p, &alaw_main[0], sizeof(alaw_main), 0); p->acc_format = SNDRV_PCM_FMTBIT_A_LAW; p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; break; case SNDRV_PCM_FORMAT_IMA_ADPCM: - err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT, - SNDRV_SB_CSP_LOAD_INITBLOCK); + err = snd_sb_csp_load(p, &ima_adpcm_init[0], sizeof(ima_adpcm_init), + SNDRV_SB_CSP_LOAD_INITBLOCK); if (err) break; if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) { - err = snd_sb_csp_firmware_load - (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0); + err = snd_sb_csp_load(p, &ima_adpcm_playback[0], + sizeof(ima_adpcm_playback), 0); p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE; } else { - err = snd_sb_csp_firmware_load - (p, CSP_PROGRAM_ADPCM_CAPTURE, 0); + err = snd_sb_csp_load(p, &ima_adpcm_capture[0], + sizeof(ima_adpcm_capture), 0); p->mode = SNDRV_SB_CSP_MODE_DSP_READ; } p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM; diff --git a/trunk/sound/isa/wavefront/wavefront.c b/trunk/sound/isa/wavefront/wavefront.c index e2fdd5fd39d0..85db535aea9b 100644 --- a/trunk/sound/isa/wavefront/wavefront.c +++ b/trunk/sound/isa/wavefront/wavefront.c @@ -402,7 +402,6 @@ static struct snd_card *snd_wavefront_card_new(int dev) init_waitqueue_head(&acard->wavefront.interrupt_sleeper); spin_lock_init(&acard->wavefront.midi.open); spin_lock_init(&acard->wavefront.midi.virtual); - acard->wavefront.card = card; card->private_free = snd_wavefront_free; return card; diff --git a/trunk/sound/isa/wavefront/wavefront_fx.c b/trunk/sound/isa/wavefront/wavefront_fx.c index 15331ed88194..4f0846feb73f 100644 --- a/trunk/sound/isa/wavefront/wavefront_fx.c +++ b/trunk/sound/isa/wavefront/wavefront_fx.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -33,17 +32,325 @@ #define FX_MSB_TRANSFER 0x02 /* transfer after DSP MSB byte written */ #define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */ -#define WAIT_IDLE 0xff +/* weird stuff, derived from port I/O tracing with dosemu */ + +static unsigned char page_zero[] __devinitdata = { +0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, +0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, +0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19, +0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01, +0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00, +0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02, +0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, +0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, +0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, +0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02, +0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40, +0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02, +0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, +0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00, +0x1d, 0x02, 0xdf +}; + +static unsigned char page_one[] __devinitdata = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, +0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, +0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, +0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00, +0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7, +0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, +0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0, +0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00, +0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0, +0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, +0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, +0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, +0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02, +0x60, 0x00, 0x1b +}; + +static unsigned char page_two[] __devinitdata = { +0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, +0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07, +0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46, +0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46, +0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, +0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05, +0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05, +0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 +}; + +static unsigned char page_three[] __devinitdata = { +0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, +0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, +0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, +0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40, +0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, +0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, +0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00, +0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 +}; + +static unsigned char page_four[] __devinitdata = { +0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, +0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, +0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, +0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, +0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22, +0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 +}; + +static unsigned char page_six[] __devinitdata = { +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, +0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, +0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, +0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00, +0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24, +0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00, +0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00, +0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a, +0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00, +0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d, +0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50, +0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00, +0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17, +0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66, +0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c, +0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00, +0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c, +0x80, 0x00, 0x7e, 0x80, 0x80 +}; + +static unsigned char page_seven[] __devinitdata = { +0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, +0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, +0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, +0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f, +0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38, +0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06, +0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b, +0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06, +0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, +0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14, +0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93, +0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00 +}; + +static unsigned char page_zero_v2[] __devinitdata = { +0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char page_one_v2[] __devinitdata = { +0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char page_two_v2[] __devinitdata = { +0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00 +}; +static unsigned char page_three_v2[] __devinitdata = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00 +}; +static unsigned char page_four_v2[] __devinitdata = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00 +}; -#define FIRMWARE_IN_THE_KERNEL +static unsigned char page_seven_v2[] __devinitdata = { +0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; -#ifdef FIRMWARE_IN_THE_KERNEL -#include "yss225.c" -static const struct firmware yss225_registers_firmware = { - .data = (u8 *)yss225_registers, - .size = sizeof yss225_registers +static unsigned char mod_v2[] __devinitdata = { +0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, +0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, +0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, +0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20, +0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, +0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff, +0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16, +0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff, +0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31, +0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, +0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, +0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00, +0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, +0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, +0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72, +0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0, +0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, +0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, +0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0, +0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00, +0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, +0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00, +0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, +0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00, +0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02, +0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, +0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, +0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 +}; +static unsigned char coefficients[] __devinitdata = { +0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, +0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, +0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, +0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00, +0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, +0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47, +0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07, +0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00, +0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01, +0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, +0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07, +0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, +0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, +0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44, +0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, +0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40, +0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a, +0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56, +0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07, +0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda, +0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05, +0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79, +0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07, +0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52, +0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03, +0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a, +0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06, +0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3, +0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20, +0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c, +0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06, +0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48, +0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, +0xba +}; +static unsigned char coefficients2[] __devinitdata = { +0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, +0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, +0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, +0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, +0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 +}; +static unsigned char coefficients3[] __devinitdata = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, +0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, +0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, +0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99, +0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02, +0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f, +0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03, +0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c, +0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03, +0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51, +0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04, +0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e, +0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05, +0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14, +0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06, +0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1, +0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07, +0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7, +0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08, +0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3, +0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09, +0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99, +0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a, +0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66, +0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a, +0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c, +0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b, +0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28, +0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c, +0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e, +0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d, +0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb, +0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e, +0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1, +0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f, +0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae, +0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff }; -#endif static int wavefront_fx_idle (snd_wavefront_t *dev) @@ -248,56 +555,465 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file, of the port I/O done, using the Yamaha faxback document as a guide to add more logic to the code. Its really pretty weird. - This is the approach of just dumping the whole I/O + There was an alternative approach of just dumping the whole I/O sequence as a series of port/value pairs and a simple loop - that outputs it. + that output it. However, I hope that eventually I'll get more + control over what this code does, and so I tried to stick with + a somewhat "algorithmic" approach. */ + int __devinit snd_wavefront_fx_start (snd_wavefront_t *dev) + { - unsigned int i; - int err; - const struct firmware *firmware; + unsigned int i, j; - if (dev->fx_initialized) - return 0; + /* Set all bits for all channels on the MOD unit to zero */ + /* XXX But why do this twice ? */ - 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 - } - - for (i = 0; i + 1 < firmware->size; i += 2) { - if (firmware->data[i] >= 8 && firmware->data[i] < 16) { - outb(firmware->data[i + 1], - dev->base + firmware->data[i]); - } else if (firmware->data[i] == WAIT_IDLE) { - if (!wavefront_fx_idle(dev)) { - err = -1; - goto out; + for (j = 0; j < 2; j++) { + for (i = 0x10; i <= 0xff; i++) { + + if (!wavefront_fx_idle (dev)) { + return (-1); } - } else { - snd_printk(KERN_ERR "invalid address" - " in register data\n"); - err = -1; - goto out; + + outb (i, dev->fx_mod_addr); + outb (0x0, dev->fx_mod_data); + } + } + + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x02, dev->fx_op); /* mute on */ + + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x44, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x42, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x43, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x7c, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x7e, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x46, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x49, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x47, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x4a, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + + /* either because of stupidity by TB's programmers, or because it + actually does something, rezero the MOD page. + */ + for (i = 0x10; i <= 0xff; i++) { + + if (!wavefront_fx_idle (dev)) { + return (-1); } + + outb (i, dev->fx_mod_addr); + outb (0x0, dev->fx_mod_data); } + /* load page zero */ - dev->fx_initialized = 1; - err = 0; + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x00, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); -out: -#ifdef FIRMWARE_IN_THE_KERNEL - if (firmware != &yss225_registers_firmware) -#endif - release_firmware(firmware); - return err; + for (i = 0; i < sizeof (page_zero); i += 2) { + outb (page_zero[i], dev->fx_dsp_msb); + outb (page_zero[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + /* Now load page one */ + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x01, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_one); i += 2) { + outb (page_one[i], dev->fx_dsp_msb); + outb (page_one[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x02, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_two); i++) { + outb (page_two[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x03, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_three); i++) { + outb (page_three[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x04, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_four); i++) { + outb (page_four[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + /* Load memory area (page six) */ + + outb (FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x06, dev->fx_dsp_page); + + for (i = 0; i < sizeof (page_six); i += 3) { + outb (page_six[i], dev->fx_dsp_addr); + outb (page_six[i+1], dev->fx_dsp_msb); + outb (page_six[i+2], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x07, dev->fx_dsp_page); + outb (0x00, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_seven); i += 2) { + outb (page_seven[i], dev->fx_dsp_msb); + outb (page_seven[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + /* Now setup the MOD area. We do this algorithmically in order to + save a little data space. It could be done in the same fashion + as the "pages". + */ + + for (i = 0x00; i <= 0x0f; i++) { + outb (0x01, dev->fx_mod_addr); + outb (i, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x02, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0xb0; i <= 0xbf; i++) { + outb (i, dev->fx_mod_addr); + outb (0x20, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0xf0; i <= 0xff; i++) { + outb (i, dev->fx_mod_addr); + outb (0x20, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0x10; i <= 0x1d; i++) { + outb (i, dev->fx_mod_addr); + outb (0xff, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x1e, dev->fx_mod_addr); + outb (0x40, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + for (i = 0x1f; i <= 0x2d; i++) { + outb (i, dev->fx_mod_addr); + outb (0xff, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x2e, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + for (i = 0x2f; i <= 0x3e; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x3f, dev->fx_mod_addr); + outb (0x20, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + for (i = 0x40; i <= 0x4d; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x4e, dev->fx_mod_addr); + outb (0x0e, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x4f, dev->fx_mod_addr); + outb (0x0e, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + + for (i = 0x50; i <= 0x6b; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x6c, dev->fx_mod_addr); + outb (0x40, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + outb (0x6d, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + outb (0x6e, dev->fx_mod_addr); + outb (0x40, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + outb (0x6f, dev->fx_mod_addr); + outb (0x40, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + for (i = 0x70; i <= 0x7f; i++) { + outb (i, dev->fx_mod_addr); + outb (0xc0, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0x80; i <= 0xaf; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0xc0; i <= 0xdd; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0xde, dev->fx_mod_addr); + outb (0x10, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0xdf, dev->fx_mod_addr); + outb (0x10, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + + for (i = 0xe0; i <= 0xef; i++) { + outb (i, dev->fx_mod_addr); + outb (0x00, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0x00; i <= 0x0f; i++) { + outb (0x01, dev->fx_mod_addr); + outb (i, dev->fx_mod_data); + outb (0x02, dev->fx_mod_addr); + outb (0x01, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (0x02, dev->fx_op); /* mute on */ + + /* Now set the coefficients and so forth for the programs above */ + + for (i = 0; i < sizeof (coefficients); i += 4) { + outb (coefficients[i], dev->fx_dsp_page); + outb (coefficients[i+1], dev->fx_dsp_addr); + outb (coefficients[i+2], dev->fx_dsp_msb); + outb (coefficients[i+3], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + /* Some settings (?) that are too small to bundle into loops */ + + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x1e, dev->fx_mod_addr); + outb (0x14, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0xde, dev->fx_mod_addr); + outb (0x20, dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0xdf, dev->fx_mod_addr); + outb (0x20, dev->fx_mod_data); + + /* some more coefficients */ + + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x06, dev->fx_dsp_page); + outb (0x78, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x40, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x03, dev->fx_dsp_addr); + outb (0x0f, dev->fx_dsp_msb); + outb (0xff, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x0b, dev->fx_dsp_addr); + outb (0x0f, dev->fx_dsp_msb); + outb (0xff, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x02, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x0a, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x46, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + outb (0x07, dev->fx_dsp_page); + outb (0x49, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + + /* Now, for some strange reason, lets reload every page + and all the coefficients over again. I have *NO* idea + why this is done. I do know that no sound is produced + is this phase is omitted. + */ + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x00, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_zero_v2); i += 2) { + outb (page_zero_v2[i], dev->fx_dsp_msb); + outb (page_zero_v2[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x01, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_one_v2); i += 2) { + outb (page_one_v2[i], dev->fx_dsp_msb); + outb (page_one_v2[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + if (!wavefront_fx_idle (dev)) return (-1); + if (!wavefront_fx_idle (dev)) return (-1); + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x02, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_two_v2); i++) { + outb (page_two_v2[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x03, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_three_v2); i++) { + outb (page_three_v2[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x04, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_four_v2); i++) { + outb (page_four_v2[i], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x06, dev->fx_dsp_page); + + /* Page six v.2 is algorithmic */ + + for (i = 0x10; i <= 0x3e; i += 2) { + outb (i, dev->fx_dsp_addr); + outb (0x00, dev->fx_dsp_msb); + outb (0x00, dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev->fx_lcr); + outb (0x07, dev->fx_dsp_page); + outb (0x10, dev->fx_dsp_addr); + + for (i = 0; i < sizeof (page_seven_v2); i += 2) { + outb (page_seven_v2[i], dev->fx_dsp_msb); + outb (page_seven_v2[i+1], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0x00; i < sizeof(mod_v2); i += 2) { + outb (mod_v2[i], dev->fx_mod_addr); + outb (mod_v2[i+1], dev->fx_mod_data); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0; i < sizeof (coefficients2); i += 4) { + outb (coefficients2[i], dev->fx_dsp_page); + outb (coefficients2[i+1], dev->fx_dsp_addr); + outb (coefficients2[i+2], dev->fx_dsp_msb); + outb (coefficients2[i+3], dev->fx_dsp_lsb); + if (!wavefront_fx_idle (dev)) return (-1); + } + + for (i = 0; i < sizeof (coefficients3); i += 2) { + int x; + + outb (0x07, dev->fx_dsp_page); + x = (i % 4) ? 0x4e : 0x4c; + outb (x, dev->fx_dsp_addr); + outb (coefficients3[i], dev->fx_dsp_msb); + outb (coefficients3[i+1], dev->fx_dsp_lsb); + } + + outb (0x00, dev->fx_op); /* mute off */ + if (!wavefront_fx_idle (dev)) return (-1); + + return (0); } diff --git a/trunk/sound/isa/wavefront/yss225.c b/trunk/sound/isa/wavefront/yss225.c deleted file mode 100644 index 9f6be3ff8ecf..000000000000 --- a/trunk/sound/isa/wavefront/yss225.c +++ /dev/null @@ -1,2739 +0,0 @@ -/* - * Copyright (c) 1998-2002 by Paul Davis - * - * 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 - */ - -/* weird stuff, derived from port I/O tracing with dosemu */ - -static const struct { - unsigned char addr; - unsigned char data; -} yss225_registers[] __devinitdata = { -/* Set all bits for all channels on the MOD unit to zero */ -{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 }, - -/* XXX But why do this twice? */ -{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 }, - -/* mute on */ -{ WAIT_IDLE }, { 0x8, 0x02 }, - -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, - -/* either because of stupidity by TB's programmers, or because it - actually does something, rezero the MOD page. */ -{ WAIT_IDLE }, { 0xe, 0x10 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x11 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x12 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x13 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x14 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x15 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x16 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x17 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x18 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x19 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x1f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x20 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x21 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x22 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x23 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x24 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x25 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x26 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x27 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x28 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x29 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x2f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x30 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x31 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x32 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x33 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x34 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x35 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x36 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x37 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x38 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x39 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x3f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x40 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x41 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x42 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x43 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x44 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x45 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x46 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x47 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x48 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x49 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x4f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x50 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x51 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x52 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x53 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x54 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x55 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x56 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x57 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x58 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x59 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x5f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x60 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x61 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x62 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x63 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x64 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x65 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x66 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x67 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x68 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x69 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x6f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x70 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x71 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x72 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x73 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x74 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x75 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x76 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x77 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x78 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x79 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x7f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x80 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x81 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x82 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x83 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x84 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x85 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x86 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x87 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x88 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x89 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x8f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x90 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x91 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x92 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x93 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x94 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x95 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x96 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x97 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x98 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x99 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9a }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9b }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9c }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9d }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9e }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0x9f }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xa9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xab }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xac }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xad }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xae }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xaf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xb9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xba }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xbf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xc9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xca }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xce }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xcf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xd9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xda }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xe9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xea }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xeb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xec }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xed }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xee }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xef }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf0 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf1 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf2 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf3 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf4 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf5 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf6 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf7 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf8 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xf9 }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfa }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfb }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfc }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfd }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xfe }, { 0xf, 0x00 }, -{ WAIT_IDLE }, { 0xe, 0xff }, { 0xf, 0x00 }, - -/* load page zero */ -{ 0x9, 0x05 }, { 0xb, 0x00 }, { 0xa, 0x00 }, - -{ 0xd, 0x01 }, { 0xc, 0x7c }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1e }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xf5 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x11 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x32 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x13 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x14 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x76 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x18 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x1a }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x17 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x10 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0xa0 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xd1 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0xf2 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x13 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xf4 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xe0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x15 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x16 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x17 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x50 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x71 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x92 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xb3 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xa0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xd4 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xf5 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x70 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0xa0 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x11 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x16 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x10 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x17 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1d }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xdf }, { WAIT_IDLE }, - -/* Now load page one */ -{ 0x9, 0x05 }, { 0xb, 0x01 }, { 0xa, 0x00 }, - -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1f }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xd8 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x19 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x18 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0xfa }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1a }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xa0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xd7 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xf7 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1c }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x3c }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x3f }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xdf }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x5d }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x7d }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0x9e }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xbe }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x03 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xdb }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xdb }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xe0 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xfb }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1b }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x02 }, { 0xa, 0x00 }, - -{ 0xc, 0xc4 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x25 }, { WAIT_IDLE }, -{ 0xc, 0x01 }, { WAIT_IDLE }, -{ 0xc, 0x06 }, { WAIT_IDLE }, -{ 0xc, 0xc4 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x25 }, { WAIT_IDLE }, -{ 0xc, 0x01 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x04 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x04 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x05 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x44 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x03 }, { 0xa, 0x00 }, - -{ 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x47 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x06 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x70 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x42 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x42 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x42 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x42 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x40 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x04 }, { 0xa, 0x00 }, - -{ 0xc, 0x63 }, { WAIT_IDLE }, -{ 0xc, 0x03 }, { WAIT_IDLE }, -{ 0xc, 0x26 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x2c }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x24 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x2e }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x01 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x22 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x22 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x22 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x62 }, { WAIT_IDLE }, -{ 0xc, 0x02 }, { WAIT_IDLE }, -{ 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xc, 0x01 }, { WAIT_IDLE }, -{ 0xc, 0x21 }, { WAIT_IDLE }, -{ 0xc, 0x01 }, { WAIT_IDLE }, - -/* Load memory area (page six) */ -{ 0x9, 0x01 }, { 0xb, 0x06 }, - -{ 0xa, 0x00 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x02 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x04 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x06 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x08 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x0a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x0c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x0e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x10 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x12 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x14 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x16 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x18 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x20 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x22 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x24 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x26 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x28 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x30 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x32 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x34 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x36 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x38 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x42 }, { 0xd, 0x03 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x44 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x46 }, { 0xd, 0x0a }, { 0xc, 0x21 }, { WAIT_IDLE }, -{ 0xa, 0x48 }, { 0xd, 0x0d }, { 0xc, 0x23 }, { WAIT_IDLE }, -{ 0xa, 0x4a }, { 0xd, 0x23 }, { 0xc, 0x1b }, { WAIT_IDLE }, -{ 0xa, 0x4c }, { 0xd, 0x37 }, { 0xc, 0x8f }, { WAIT_IDLE }, -{ 0xa, 0x4e }, { 0xd, 0x45 }, { 0xc, 0x77 }, { WAIT_IDLE }, -{ 0xa, 0x50 }, { 0xd, 0x52 }, { 0xc, 0xe2 }, { WAIT_IDLE }, -{ 0xa, 0x52 }, { 0xd, 0x1c }, { 0xc, 0x92 }, { WAIT_IDLE }, -{ 0xa, 0x54 }, { 0xd, 0x1c }, { 0xc, 0x52 }, { WAIT_IDLE }, -{ 0xa, 0x56 }, { 0xd, 0x07 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x58 }, { 0xd, 0x2f }, { 0xc, 0xc6 }, { WAIT_IDLE }, -{ 0xa, 0x5a }, { 0xd, 0x0b }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x5c }, { 0xd, 0x30 }, { 0xc, 0x06 }, { WAIT_IDLE }, -{ 0xa, 0x5e }, { 0xd, 0x17 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x60 }, { 0xd, 0x3d }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xa, 0x62 }, { 0xd, 0x29 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x64 }, { 0xd, 0x3e }, { 0xc, 0x41 }, { WAIT_IDLE }, -{ 0xa, 0x66 }, { 0xd, 0x39 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x68 }, { 0xd, 0x4c }, { 0xc, 0x48 }, { WAIT_IDLE }, -{ 0xa, 0x6a }, { 0xd, 0x49 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x6c }, { 0xd, 0x4c }, { 0xc, 0x6c }, { WAIT_IDLE }, -{ 0xa, 0x6e }, { 0xd, 0x11 }, { 0xc, 0xd2 }, { WAIT_IDLE }, -{ 0xa, 0x70 }, { 0xd, 0x16 }, { 0xc, 0x0c }, { WAIT_IDLE }, -{ 0xa, 0x72 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x74 }, { 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xa, 0x76 }, { 0xd, 0x0f }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x78 }, { 0xd, 0x00 }, { 0xc, 0x80 }, { WAIT_IDLE }, -{ 0xa, 0x7a }, { 0xd, 0x13 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x7c }, { 0xd, 0x80 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x7e }, { 0xd, 0x80 }, { 0xc, 0x80 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x07 }, { 0xa, 0x00 }, - -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x08 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0xe9 }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x8c }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x8c }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x1a }, { 0xc, 0x75 }, { WAIT_IDLE }, -{ 0xd, 0x0d }, { 0xc, 0x8b }, { WAIT_IDLE }, -{ 0xd, 0x04 }, { 0xc, 0xe9 }, { WAIT_IDLE }, -{ 0xd, 0x0b }, { 0xc, 0x16 }, { WAIT_IDLE }, -{ 0xd, 0x1a }, { 0xc, 0x38 }, { WAIT_IDLE }, -{ 0xd, 0x0d }, { 0xc, 0xc8 }, { WAIT_IDLE }, -{ 0xd, 0x04 }, { 0xc, 0x6f }, { WAIT_IDLE }, -{ 0xd, 0x0b }, { 0xc, 0x91 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x8f }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x62 }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x62 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x7b }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x97 }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0x97 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x52 }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0xf6 }, { WAIT_IDLE }, -{ 0xd, 0x06 }, { 0xc, 0xf6 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x19 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x55 }, { WAIT_IDLE }, -{ 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -/* Now setup the MOD area. */ -{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x08 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x09 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0a }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0b }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0c }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0d }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0e }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0f }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, - -{ 0xe, 0xb0 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb1 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb2 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb3 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb4 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb5 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb6 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb7 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb8 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb9 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xba }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xbb }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xbc }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xbd }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xbe }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xbf }, { 0xf, 0x20 }, { WAIT_IDLE }, - -{ 0xe, 0xf0 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf1 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf2 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf3 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf4 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf5 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf6 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf7 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf8 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf9 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xfa }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xfb }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xfc }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xfd }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xfe }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xff }, { 0xf, 0x20 }, { WAIT_IDLE }, - -{ 0xe, 0x10 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x11 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x12 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x13 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x14 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x15 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x16 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x17 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x18 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x19 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x1a }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x1b }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x1c }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x1d }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x1e }, { 0xf, 0x40 }, { WAIT_IDLE }, -{ 0xe, 0x1f }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x20 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x21 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x22 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x23 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x24 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x25 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x26 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x27 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x28 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x29 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x2a }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x2b }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x2c }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x2d }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x2e }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x2f }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x30 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x31 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x32 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x33 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x34 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x35 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x36 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x37 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x38 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x39 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3c }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3e }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x3f }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0x40 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x41 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x42 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x43 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x44 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x45 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x46 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x47 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x48 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x49 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x4a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x4b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x4c }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x4d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x4e }, { 0xf, 0x0e }, { WAIT_IDLE }, -{ 0xe, 0x4f }, { 0xf, 0x0e }, { WAIT_IDLE }, -{ 0xe, 0x50 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x51 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x52 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x53 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x54 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x55 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x56 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x57 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x58 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x59 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5c }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5e }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x5f }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x60 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x61 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x62 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x63 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x64 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x65 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x66 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x67 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x68 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x69 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x6a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x6b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x6c }, { 0xf, 0x40 }, { WAIT_IDLE }, -{ 0xe, 0x6d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x6e }, { 0xf, 0x40 }, { WAIT_IDLE }, -{ 0xe, 0x6f }, { 0xf, 0x40 }, { WAIT_IDLE }, -{ 0xe, 0x70 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x71 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x72 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x73 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x74 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x75 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x76 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x77 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x78 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x79 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7a }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7b }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7c }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7d }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7e }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x7f }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x80 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x81 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x82 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x83 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x84 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x85 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x86 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x87 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x88 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x89 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8c }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8e }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x8f }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x90 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x91 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x92 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x93 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x94 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x95 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x96 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x97 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x98 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x99 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9a }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9b }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9c }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9d }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9e }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x9f }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa8 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa9 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xaa }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xab }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xac }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xad }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xae }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xaf }, { 0xf, 0x00 }, { WAIT_IDLE }, - -{ 0xe, 0xc0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc8 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc9 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xca }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xcb }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xcc }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xcd }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xce }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xcf }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd8 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd9 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xda }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xdb }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xdc }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xdd }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xde }, { 0xf, 0x10 }, { WAIT_IDLE }, -{ 0xe, 0xdf }, { 0xf, 0x10 }, { WAIT_IDLE }, -{ 0xe, 0xe0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe8 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe9 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xea }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xeb }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xec }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xed }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xee }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xef }, { 0xf, 0x00 }, { WAIT_IDLE }, - -{ 0xe, 0x01 }, { 0xf, 0x00 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x01 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x02 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x03 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x04 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x05 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x06 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x07 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x08 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x09 }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0a }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0b }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0c }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0d }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0e }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x0f }, { 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, - -/* mute on */ -{ 0x8, 0x02 }, - -/* Now set the coefficients and so forth for the programs above */ -{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x4b }, { 0xd, 0x03 }, { 0xc, 0x11 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x4d }, { 0xd, 0x01 }, { 0xc, 0x32 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x01 }, { 0xa, 0x40 }, { 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xb, 0x01 }, { 0xa, 0x41 }, { 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x47 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x4a }, { 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x00 }, { 0xd, 0x01 }, { 0xc, 0x1c }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x44 }, { 0xd, 0x01 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x42 }, { 0xd, 0x01 }, { 0xc, 0x1a }, { WAIT_IDLE }, -{ 0xb, 0x00 }, { 0xa, 0x43 }, { 0xd, 0x01 }, { 0xc, 0x20 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x01 }, { 0xa, 0x40 }, { 0xd, 0x02 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xb, 0x01 }, { 0xa, 0x41 }, { 0xd, 0x02 }, { 0xc, 0x60 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x44 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x42 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x43 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x40 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x41 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x51 }, { 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x50 }, { 0xd, 0x06 }, { 0xc, 0x40 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4f }, { 0xd, 0x03 }, { 0xc, 0x81 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x53 }, { 0xd, 0x1a }, { 0xc, 0x76 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x54 }, { 0xd, 0x0d }, { 0xc, 0x8b }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x55 }, { 0xd, 0x04 }, { 0xc, 0xe9 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x56 }, { 0xd, 0x0b }, { 0xc, 0x17 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x57 }, { 0xd, 0x1a }, { 0xc, 0x38 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x58 }, { 0xd, 0x0d }, { 0xc, 0xc9 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x59 }, { 0xd, 0x04 }, { 0xc, 0x6f }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x5a }, { 0xd, 0x0b }, { 0xc, 0x91 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x73 }, { 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x74 }, { 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x75 }, { 0xd, 0x04 }, { 0xc, 0xd9 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x76 }, { 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x77 }, { 0xd, 0x14 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x78 }, { 0xd, 0x0d }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x79 }, { 0xd, 0x04 }, { 0xc, 0xd9 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7a }, { 0xd, 0x05 }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x5e }, { 0xd, 0x03 }, { 0xc, 0x68 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x5c }, { 0xd, 0x04 }, { 0xc, 0x31 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x5d }, { 0xd, 0x04 }, { 0xc, 0x31 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x62 }, { 0xd, 0x03 }, { 0xc, 0x52 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x60 }, { 0xd, 0x04 }, { 0xc, 0x76 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x61 }, { 0xd, 0x04 }, { 0xc, 0x76 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x66 }, { 0xd, 0x03 }, { 0xc, 0x2e }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x64 }, { 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x65 }, { 0xd, 0x04 }, { 0xc, 0xda }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x6a }, { 0xd, 0x02 }, { 0xc, 0xf6 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x68 }, { 0xd, 0x05 }, { 0xc, 0x62 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x69 }, { 0xd, 0x05 }, { 0xc, 0x62 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x46 }, { 0xd, 0x0a }, { 0xc, 0x22 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x48 }, { 0xd, 0x0d }, { 0xc, 0x24 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x6e }, { 0xd, 0x11 }, { 0xc, 0xd3 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x70 }, { 0xd, 0x15 }, { 0xc, 0xcb }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x52 }, { 0xd, 0x20 }, { 0xc, 0x93 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x54 }, { 0xd, 0x20 }, { 0xc, 0x54 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x4a }, { 0xd, 0x27 }, { 0xc, 0x1d }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x58 }, { 0xd, 0x2f }, { 0xc, 0xc8 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x5c }, { 0xd, 0x30 }, { 0xc, 0x07 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x4c }, { 0xd, 0x37 }, { 0xc, 0x90 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x60 }, { 0xd, 0x3d }, { 0xc, 0xdb }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x64 }, { 0xd, 0x3e }, { 0xc, 0x42 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x4e }, { 0xd, 0x45 }, { 0xc, 0x78 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x68 }, { 0xd, 0x4c }, { 0xc, 0x48 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x6c }, { 0xd, 0x4c }, { 0xc, 0x6c }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x50 }, { 0xd, 0x52 }, { 0xc, 0xe2 }, { WAIT_IDLE }, -{ 0xb, 0x06 }, { 0xa, 0x42 }, { 0xd, 0x02 }, { 0xc, 0xba }, { WAIT_IDLE }, - -/* Some settings (?) */ -{ WAIT_IDLE }, { 0xe, 0x1e }, { 0xf, 0x14 }, -{ WAIT_IDLE }, { 0xe, 0xde }, { 0xf, 0x20 }, -{ WAIT_IDLE }, { 0xe, 0xdf }, { 0xf, 0x20 }, - -/* some more coefficients */ -{ WAIT_IDLE }, { 0xb, 0x06 }, { 0xa, 0x78 }, { 0xd, 0x00 }, { 0xc, 0x40 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x03 }, { 0xd, 0x0f }, { 0xc, 0xff }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x0b }, { 0xd, 0x0f }, { 0xc, 0xff }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x02 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x0a }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ WAIT_IDLE }, { 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, - -/* Now, for some strange reason, lets reload every page - and all the coefficients over again. I have *NO* idea - why this is done. I do know that no sound is produced - is this phase is omitted. */ -{ 0x9, 0x05 }, { 0xb, 0x00 }, { 0xa, 0x10 }, - -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x02 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x01 }, { 0xa, 0x10 }, - -{ 0xd, 0x01 }, { 0xc, 0xc0 }, { WAIT_IDLE }, -{ 0xd, 0x01 }, { 0xc, 0xfa }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x1a }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -{ WAIT_IDLE }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x02 }, { 0xa, 0x10 }, - -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x46 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x03 }, { 0xa, 0x10 }, - -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x04 }, { 0xa, 0x10 }, - -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xc, 0x00 }, { WAIT_IDLE }, - -/* Page six v.2 */ -{ 0x9, 0x01 }, { 0xb, 0x06 }, - -{ 0xa, 0x10 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x12 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x14 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x16 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x18 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x1e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x20 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x22 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x24 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x26 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x28 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x2e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x30 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x32 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x34 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x36 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x38 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xa, 0x3e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0x9, 0x05 }, { 0xb, 0x07 }, { 0xa, 0x10 }, - -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xb0 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb1 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb2 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb3 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb4 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb5 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb6 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xb7 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf0 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf1 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf2 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf3 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf4 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf5 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf6 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0xf7 }, { 0xf, 0x20 }, { WAIT_IDLE }, -{ 0xe, 0x10 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x11 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x12 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x13 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x14 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x15 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x16 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x17 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x20 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x21 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x22 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x23 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x24 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x25 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x26 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x27 }, { 0xf, 0xff }, { WAIT_IDLE }, -{ 0xe, 0x30 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x31 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x32 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x33 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x34 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x35 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x36 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x37 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x40 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x41 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x42 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x43 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x44 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x45 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x46 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x47 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x50 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x51 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x52 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x53 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x54 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x55 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x56 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x57 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x60 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x61 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x62 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x63 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x64 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x65 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x66 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x67 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x70 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x71 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x72 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x73 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x74 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x75 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x76 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x77 }, { 0xf, 0xc0 }, { WAIT_IDLE }, -{ 0xe, 0x80 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x81 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x82 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x83 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x84 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x85 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x86 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x87 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x90 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x91 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x92 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x93 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x94 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x95 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x96 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x97 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xa7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xc7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xd7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe0 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe1 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe2 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe3 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe4 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe5 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe6 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0xe7 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x00 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x02 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x03 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x04 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x05 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x06 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, -{ 0xe, 0x01 }, { 0xf, 0x07 }, { WAIT_IDLE }, -{ 0xe, 0x02 }, { 0xf, 0x01 }, { WAIT_IDLE }, - -{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x45 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x48 }, { 0xd, 0x0f }, { 0xc, 0xff }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7b }, { 0xd, 0x04 }, { 0xc, 0xcc }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7d }, { 0xd, 0x04 }, { 0xc, 0xcc }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x7e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x46 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x49 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x47 }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4a }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x00 }, { WAIT_IDLE }, - -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x00 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x00 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x01 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x01 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x02 }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x02 }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x03 }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x03 }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x04 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x04 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x05 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x05 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x06 }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x06 }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x07 }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x07 }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x08 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x08 }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x09 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x09 }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0a }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0a }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0b }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0b }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x00 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x28 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x51 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0x7a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xa3 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xcc }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0c }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0c }, { 0xc, 0xf5 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x1e }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x47 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x70 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0x99 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0xc2 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0d }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0d }, { 0xc, 0xeb }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x14 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x3d }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x66 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0x8f }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0xb8 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0e }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0e }, { 0xc, 0xe1 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x0a }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x33 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x5c }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0x85 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xae }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xd7 }, -{ 0xb, 0x07 }, { 0xa, 0x4c }, { 0xd, 0x0f }, { 0xc, 0xff }, -{ 0xb, 0x07 }, { 0xa, 0x4e }, { 0xd, 0x0f }, { 0xc, 0xff }, - -/* mute off */ -{ 0x8, 0x00 }, { WAIT_IDLE } -}; diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 1bcfb3aac18d..8a6b1803c763 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -236,7 +236,7 @@ config SND_CS5535AUDIO config SND_DARLA20 tristate "(Echoaudio) Darla20" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Darla. @@ -247,7 +247,7 @@ config SND_DARLA20 config SND_GINA20 tristate "(Echoaudio) Gina20" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Gina. @@ -258,7 +258,7 @@ config SND_GINA20 config SND_LAYLA20 tristate "(Echoaudio) Layla20" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_RAWMIDI select SND_PCM help @@ -270,7 +270,7 @@ config SND_LAYLA20 config SND_DARLA24 tristate "(Echoaudio) Darla24" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Darla24. @@ -281,7 +281,7 @@ config SND_DARLA24 config SND_GINA24 tristate "(Echoaudio) Gina24" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Gina24. @@ -292,7 +292,7 @@ config SND_GINA24 config SND_LAYLA24 tristate "(Echoaudio) Layla24" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_RAWMIDI select SND_PCM help @@ -304,7 +304,7 @@ config SND_LAYLA24 config SND_MONA tristate "(Echoaudio) Mona" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_RAWMIDI select SND_PCM help @@ -316,7 +316,7 @@ config SND_MONA config SND_MIA tristate "(Echoaudio) Mia" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_RAWMIDI select SND_PCM help @@ -328,7 +328,7 @@ config SND_MIA config SND_ECHO3G tristate "(Echoaudio) 3G cards" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_RAWMIDI select SND_PCM help @@ -340,7 +340,7 @@ config SND_ECHO3G config SND_INDIGO tristate "(Echoaudio) Indigo" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Indigo. @@ -351,7 +351,7 @@ config SND_INDIGO config SND_INDIGOIO tristate "(Echoaudio) Indigo IO" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Indigo IO. @@ -362,7 +362,7 @@ config SND_INDIGOIO config SND_INDIGODJ tristate "(Echoaudio) Indigo DJ" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_PCM help Say 'Y' or 'M' to include support for Echoaudio Indigo DJ. @@ -373,7 +373,6 @@ config SND_INDIGODJ config SND_EMU10K1 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" depends on SND - select FW_LOADER select SND_HWDEP select SND_RAWMIDI select SND_AC97_CODEC @@ -576,7 +575,6 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -587,7 +585,6 @@ config SND_KORG1212 config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND - select FW_LOADER select SND_AC97_CODEC help Say Y here to include support for soundcards based on ESS Maestro 3 @@ -632,7 +629,7 @@ config SND_PCXHR config SND_RIPTIDE tristate "Conexant Riptide" depends on SND - select FW_LOADER + depends on FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -737,7 +734,6 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 74ed81081478..d2994cb4c8c9 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -111,7 +111,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL }, { 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, { 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, -{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL }, +{ 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL }, { 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, { 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, { 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ @@ -194,13 +194,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { static void update_power_regs(struct snd_ac97 *ac97); -#ifdef CONFIG_SND_AC97_POWER_SAVE -#define ac97_is_power_save_mode(ac97) \ - ((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save) -#else -#define ac97_is_power_save_mode(ac97) 0 -#endif - /* * I/O routines @@ -989,8 +982,8 @@ static int snd_ac97_free(struct snd_ac97 *ac97) { if (ac97) { #ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); + if (ac97->power_workq) + destroy_workqueue(ac97->power_workq); #endif snd_ac97_proc_done(ac97); if (ac97->bus) @@ -1191,13 +1184,13 @@ static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg, /* * set dB information */ -static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); -static const unsigned int *find_db_scale(unsigned int maxval) +static unsigned int *find_db_scale(unsigned int maxval) { switch (maxval) { case 0x0f: return db_scale_4bit; @@ -1207,8 +1200,8 @@ static const unsigned int *find_db_scale(unsigned int maxval) return NULL; } -static void set_tlv_db_scale(struct snd_kcontrol *kctl, const unsigned int *tlv) -{ +static void set_tlv_db_scale(struct snd_kcontrol *kctl, unsigned int *tlv) +{ kctl->tlv.p = tlv; if (tlv) kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; @@ -1996,6 +1989,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, mutex_init(&ac97->reg_mutex); mutex_init(&ac97->page_mutex); #ifdef CONFIG_SND_AC97_POWER_SAVE + ac97->power_workq = create_workqueue("ac97"); INIT_DELAYED_WORK(&ac97->power_work, do_update_power); #endif @@ -2281,13 +2275,15 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97) udelay(100); power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ snd_ac97_write(ac97, AC97_POWERDOWN, power); - if (ac97_is_power_save_mode(ac97)) { +#ifdef CONFIG_SND_AC97_POWER_SAVE + if (power_save) { udelay(100); /* AC-link powerdown, internal Clk disable */ /* FIXME: this may cause click noises on some boards */ power |= AC97_PD_PR4 | AC97_PD_PR5; snd_ac97_write(ac97, AC97_POWERDOWN, power); } +#endif } @@ -2341,16 +2337,14 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) } } - if (ac97_is_power_save_mode(ac97) && !powerup) + if (power_save && !powerup && ac97->power_workq) /* adjust power-down bits after two seconds delay * (for avoiding loud click noises for many (OSS) apps * that open/close frequently) */ - schedule_delayed_work(&ac97->power_work, HZ*2); - else { - cancel_delayed_work(&ac97->power_work); + queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2); + else update_power_regs(ac97); - } return 0; } @@ -2363,15 +2357,19 @@ static void update_power_regs(struct snd_ac97 *ac97) unsigned int power_up, bits; int i; - power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC); - power_up |= (1 << PWIDX_MIC); - if (ac97->scaps & AC97_SCAP_SURROUND_DAC) - power_up |= (1 << PWIDX_SURR); - if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) - power_up |= (1 << PWIDX_CLFE); #ifdef CONFIG_SND_AC97_POWER_SAVE - if (ac97_is_power_save_mode(ac97)) + if (power_save) power_up = ac97->power_up; + else { +#endif + power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC); + power_up |= (1 << PWIDX_MIC); + if (ac97->scaps & AC97_SCAP_SURROUND_DAC) + power_up |= (1 << PWIDX_SURR); + if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) + power_up |= (1 << PWIDX_CLFE); +#ifdef CONFIG_SND_AC97_POWER_SAVE + } #endif if (power_up) { if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) { @@ -2416,10 +2414,6 @@ void snd_ac97_suspend(struct snd_ac97 *ac97) return; if (ac97->build_ops->suspend) ac97->build_ops->suspend(ac97); -#ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); -#endif snd_ac97_powerdown(ac97); } diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 641d0c8d659e..e813968e0cf8 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -54,7 +54,7 @@ static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontro /* replace with a new TLV */ static void reset_tlv(struct snd_ac97 *ac97, const char *name, - const unsigned int *tlv) + unsigned int *tlv) { struct snd_ctl_elem_id sid; struct snd_kcontrol *kctl; @@ -190,28 +190,14 @@ static inline int is_clfe_on(struct snd_ac97 *ac97) return ac97->channel_mode >= 2; } -/* system has shared jacks with surround out enabled */ -static inline int is_shared_surrout(struct snd_ac97 *ac97) -{ - return !ac97->indep_surround && is_surround_on(ac97); -} - -/* system has shared jacks with center/lfe out enabled */ -static inline int is_shared_clfeout(struct snd_ac97 *ac97) -{ - return !ac97->indep_surround && is_clfe_on(ac97); -} - -/* system has shared jacks with line in enabled */ static inline int is_shared_linein(struct snd_ac97 *ac97) { - return !ac97->indep_surround && !is_surround_on(ac97); + return ! ac97->indep_surround && is_surround_on(ac97); } -/* system has shared jacks with mic in enabled */ static inline int is_shared_micin(struct snd_ac97 *ac97) { - return !ac97->indep_surround && !is_clfe_on(ac97); + return ! ac97->indep_surround && is_clfe_on(ac97); } @@ -955,9 +941,6 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97) { int err; - /* the register bit is writable, but the function is not implemented: */ - snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL); - snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback"); if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0) return err; @@ -1569,7 +1552,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = { AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */ }; -static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); static int patch_ad1885_specific(struct snd_ac97 * ac97) { @@ -1626,22 +1609,19 @@ int patch_ad1886(struct snd_ac97 * ac97) return 0; } -/* MISC bits (AD1888/AD1980/AD1985 register 0x76) */ +/* MISC bits */ #define AC97_AD198X_MBC 0x0003 /* mic boost */ #define AC97_AD198X_MBC_20 0x0000 /* +20dB */ #define AC97_AD198X_MBC_10 0x0001 /* +10dB */ #define AC97_AD198X_MBC_30 0x0002 /* +30dB */ #define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */ -#define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */ -#define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */ -#define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD) -#define AC97_AD198X_VREF_SHIFT 2 +#define AC97_AD198X_VREFH 0x0008 /* 2.25V, 3.7V */ +#define AC97_AD198X_VREF_0 0x000c /* 0V */ #define AC97_AD198X_SRU 0x0010 /* sample rate unlock */ #define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */ #define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */ #define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */ -#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */ - /* 0 = 6-to-4, 1 = 6-to-2 downmix */ +#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */ #define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */ #define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */ #define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */ @@ -1650,83 +1630,6 @@ int patch_ad1886(struct snd_ac97 * ac97) #define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ #define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ -/* MISC 1 bits (AD1986 register 0x76) */ -#define AC97_AD1986_MBC 0x0003 /* mic boost */ -#define AC97_AD1986_MBC_20 0x0000 /* +20dB */ -#define AC97_AD1986_MBC_10 0x0001 /* +10dB */ -#define AC97_AD1986_MBC_30 0x0002 /* +30dB */ -#define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */ -#define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */ -#define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0) -#define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */ -#define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */ -#define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */ -#define AC97_AD1986_SRU 0x0010 /* sample rate unlock */ -#define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */ -#define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */ -#define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */ -#define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */ - /* 0 = 6-to-4, 1 = 6-to-2 downmix */ -#define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */ -#define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */ -#define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */ -#define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */ -#define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */ -#define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */ - -/* MISC 2 bits (AD1986 register 0x70) */ -#define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */ - -#define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */ -#define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */ -#define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */ -#define AC97_AD1986_CVREF_MASK \ - (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0) -#define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */ -#define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */ -#define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */ -#define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */ -#define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */ -#define AC97_AD1986_MVREF_MASK \ - (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0) - -/* MISC 3 bits (AD1986 register 0x7a) */ -#define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */ - -#define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */ -#define AC97_AD1986_GPO 0x0008 /* General Purpose Out */ -#define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */ -#define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */ -#define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */ -#define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */ -#define AC97_AD1986_LVREF_MASK \ - (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0) -#define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */ -#define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */ -#define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */ - /* input select Surround DACs */ -#define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */ - /* select C/LFE DACs */ -#define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */ - -/* Serial Config bits (AD1986 register 0x74) (incomplete) */ -#define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */ -#define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */ -#define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */ -#define AC97_AD1986_OMS_MASK \ - (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0) -#define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */ -#define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */ -#define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */ -#define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */ - /* are MIC sources */ -#define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */ - /* are MIC sources */ -#define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */ - /* are MIC sources */ -#define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */ - /* are MIC sources */ - static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2049,80 +1952,8 @@ int patch_ad1980(struct snd_ac97 * ac97) return 0; } -static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"}; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - static const int reg2ctrl[4] = {2, 0, 1, 3}; - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short val; - val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK) - >> AC97_AD198X_VREF_SHIFT; - ucontrol->value.enumerated.item[0] = reg2ctrl[val]; - return 0; -} - -static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - static const int ctrl2reg[4] = {1, 2, 0, 3}; - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short val; - - if (ucontrol->value.enumerated.item[0] > 3 - || ucontrol->value.enumerated.item[0] < 0) - return -EINVAL; - val = ctrl2reg[ucontrol->value.enumerated.item[0]] - << AC97_AD198X_VREF_SHIFT; - return snd_ac97_update_bits(ac97, AC97_AD_MISC, - AC97_AD198X_VREF_MASK, val); -} - static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { - AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Exchange Front/Surround", - .info = snd_ac97_ad1888_lohpsel_info, - .get = snd_ac97_ad1888_lohpsel_get, - .put = snd_ac97_ad1888_lohpsel_put - }, - AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), - AC97_SINGLE("Spread Front to Surround and Center/LFE", - AC97_AD_MISC, 7, 1, 0), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Downmix", - .info = snd_ac97_ad1888_downmix_info, - .get = snd_ac97_ad1888_downmix_get, - .put = snd_ac97_ad1888_downmix_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "V_REFOUT", - .info = snd_ac97_ad1985_vrefout_info, - .get = snd_ac97_ad1985_vrefout_get, - .put = snd_ac97_ad1985_vrefout_put - }, - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, - - AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), - AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), + AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0) }; static void ad1985_update_jacks(struct snd_ac97 *ac97) @@ -2136,16 +1967,9 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97) { int err; - /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ - snd_ac97_rename_vol_ctl(ac97, "Master Playback", - "Master Surround Playback"); - snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); - - if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0) + if ((err = patch_ad1980_specific(ac97)) < 0) return err; - - return patch_build_controls(ac97, snd_ac97_ad1985_controls, - ARRAY_SIZE(snd_ac97_ad1985_controls)); + return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls)); } static struct snd_ac97_build_ops patch_ad1985_build_ops = { @@ -2165,311 +1989,24 @@ int patch_ad1985(struct snd_ac97 * ac97) ac97->build_ops = &patch_ad1985_build_ops; misc = snd_ac97_read(ac97, AC97_AD_MISC); /* switch front/surround line-out/hp-out */ + /* center/LFE, mic in 3.75V mode */ /* AD-compatible mode */ /* Stereo mutes enabled */ + /* in accordance with ADI driver: misc | 0x5c28 */ snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | + AC97_AD198X_VREFH | AC97_AD198X_LOSEL | AC97_AD198X_HPSEL | + AC97_AD198X_CLDIS | + AC97_AD198X_LODIS | AC97_AD198X_MSPLT | AC97_AD198X_AC97NC); ac97->flags |= AC97_STEREO_MUTES; - - /* update current jack configuration */ - ad1985_update_jacks(ac97); - /* on AD1985 rev. 3, AC'97 revision bits are zero */ ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23; return 0; } -static int snd_ac97_ad1986_bool_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 snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short val; - - val = ac97->regs[AC97_AD_MISC3]; - ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0; - return 0; -} - -static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - int ret0; - int ret1; - int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0; - - ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL, - ucontrol->value.integer.value[0] != 0 - ? AC97_AD1986_LOSEL : 0); - if (ret0 < 0) - return ret0; - - /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ - ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, - (ucontrol->value.integer.value[0] != 0 - || sprd) - ? AC97_AD1986_SOSEL : 0); - if (ret1 < 0) - return ret1; - - return (ret0 > 0 || ret1 > 0) ? 1 : 0; -} - -static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short val; - - val = ac97->regs[AC97_AD_MISC]; - ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0; - return 0; -} - -static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - int ret0; - int ret1; - int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0; - - ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD, - ucontrol->value.integer.value[0] != 0 - ? AC97_AD1986_SPRD : 0); - if (ret0 < 0) - return ret0; - - /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */ - ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL, - (ucontrol->value.integer.value[0] != 0 - || sprd) - ? AC97_AD1986_SOSEL : 0); - if (ret1 < 0) - return ret1; - - return (ret0 > 0 || ret1 > 0) ? 1 : 0; -} - -static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein; - return 0; -} - -static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned char swap = ucontrol->value.integer.value[0] != 0; - - if (swap != ac97->spec.ad18xx.swap_mic_linein) { - ac97->spec.ad18xx.swap_mic_linein = swap; - if (ac97->build_ops->update_jacks) - ac97->build_ops->update_jacks(ac97); - return 1; - } - return 0; -} - -static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* Use MIC_1/2 V_REFOUT as the "get" value */ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short val; - unsigned short reg = ac97->regs[AC97_AD_MISC2]; - if ((reg & AC97_AD1986_MVREF0) != 0) - val = 2; - else if ((reg & AC97_AD1986_MVREF1) != 0) - val = 3; - else if ((reg & AC97_AD1986_MVREF2) != 0) - val = 1; - else - val = 0; - ucontrol->value.enumerated.item[0] = val; - return 0; -} - -static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); - unsigned short cval; - unsigned short lval; - unsigned short mval; - int cret; - int lret; - int mret; - - switch (ucontrol->value.enumerated.item[0]) - { - case 0: /* High-Z */ - cval = 0; - lval = 0; - mval = 0; - break; - case 1: /* 3.7 V */ - cval = AC97_AD1986_CVREF2; - lval = AC97_AD1986_LVREF2; - mval = AC97_AD1986_MVREF2; - break; - case 2: /* 2.25 V */ - cval = AC97_AD1986_CVREF0; - lval = AC97_AD1986_LVREF0; - mval = AC97_AD1986_MVREF0; - break; - case 3: /* 0 V */ - cval = AC97_AD1986_CVREF1; - lval = AC97_AD1986_LVREF1; - mval = AC97_AD1986_MVREF1; - break; - default: - return -EINVAL; - } - - cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, - AC97_AD1986_CVREF_MASK, cval); - if (cret < 0) - return cret; - lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3, - AC97_AD1986_LVREF_MASK, lval); - if (lret < 0) - return lret; - mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2, - AC97_AD1986_MVREF_MASK, mval); - if (mret < 0) - return mret; - - return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0; -} - -static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = { - AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Exchange Front/Surround", - .info = snd_ac97_ad1986_bool_info, - .get = snd_ac97_ad1986_lososel_get, - .put = snd_ac97_ad1986_lososel_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Exchange Mic/Line In", - .info = snd_ac97_ad1986_bool_info, - .get = snd_ac97_ad1986_miclisel_get, - .put = snd_ac97_ad1986_miclisel_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Spread Front to Surround and Center/LFE", - .info = snd_ac97_ad1986_bool_info, - .get = snd_ac97_ad1986_spread_get, - .put = snd_ac97_ad1986_spread_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Downmix", - .info = snd_ac97_ad1888_downmix_info, - .get = snd_ac97_ad1888_downmix_get, - .put = snd_ac97_ad1888_downmix_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "V_REFOUT", - .info = snd_ac97_ad1985_vrefout_info, - .get = snd_ac97_ad1986_vrefout_get, - .put = snd_ac97_ad1986_vrefout_put - }, - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, - - AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), - AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0) -}; - -static void ad1986_update_jacks(struct snd_ac97 *ac97) -{ - unsigned short misc_val = 0; - unsigned short ser_val; - - /* disable SURROUND and CENTER/LFE if not surround mode */ - if (! is_surround_on(ac97)) - misc_val |= AC97_AD1986_SODIS; - if (! is_clfe_on(ac97)) - misc_val |= AC97_AD1986_CLDIS; - - /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */ - if (is_shared_linein(ac97)) - misc_val |= AC97_AD1986_LISEL_SURR; - else if (ac97->spec.ad18xx.swap_mic_linein != 0) - misc_val |= AC97_AD1986_LISEL_MIC; - snd_ac97_update_bits(ac97, AC97_AD_MISC, - AC97_AD1986_SODIS | AC97_AD1986_CLDIS | - AC97_AD1986_LISEL_MASK, - misc_val); - - /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */ - if (is_shared_micin(ac97)) - ser_val = AC97_AD1986_OMS_C; - else if (ac97->spec.ad18xx.swap_mic_linein != 0) - ser_val = AC97_AD1986_OMS_L; - else - ser_val = AC97_AD1986_OMS_M; - snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, - AC97_AD1986_OMS_MASK, - ser_val); -} - -static int patch_ad1986_specific(struct snd_ac97 *ac97) -{ - int err; - - if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0) - return err; - - return patch_build_controls(ac97, snd_ac97_ad1986_controls, - ARRAY_SIZE(snd_ac97_ad1985_controls)); -} - -static struct snd_ac97_build_ops patch_ad1986_build_ops = { - .build_post_spdif = patch_ad198x_post_spdif, - .build_specific = patch_ad1986_specific, -#ifdef CONFIG_PM - .resume = ad18xx_resume, -#endif - .update_jacks = ad1986_update_jacks, -}; - -int patch_ad1986(struct snd_ac97 * ac97) -{ - patch_ad1881(ac97); - ac97->build_ops = &patch_ad1986_build_ops; - ac97->flags |= AC97_STEREO_MUTES; - - /* update current jack configuration */ - ad1986_update_jacks(ac97); - - return 0; -} - - /* * realtek ALC65x/850 codecs */ @@ -2477,12 +2014,12 @@ static void alc650_update_jacks(struct snd_ac97 *ac97) { int shared; - /* shared Line-In / Surround Out */ - shared = is_shared_surrout(ac97); + /* shared Line-In */ + shared = is_shared_linein(ac97); snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9, shared ? (1 << 9) : 0); - /* update shared Mic In / Center/LFE Out */ - shared = is_shared_clfeout(ac97); + /* update shared Mic */ + shared = is_shared_micin(ac97); /* disable/enable vref */ snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, shared ? (1 << 12) : 0); @@ -2527,7 +2064,7 @@ static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = { /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ }; -static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); static int patch_alc650_specific(struct snd_ac97 * ac97) { @@ -2612,12 +2149,12 @@ static void alc655_update_jacks(struct snd_ac97 *ac97) { int shared; - /* shared Line-In / Surround Out */ - shared = is_shared_surrout(ac97); + /* shared Line-In */ + shared = is_shared_linein(ac97); ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9, shared ? (1 << 9) : 0, 0); - /* update shared Mic In / Center/LFE Out */ - shared = is_shared_clfeout(ac97); + /* update shared mic */ + shared = is_shared_micin(ac97); /* misc control; vrefout disable */ snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, shared ? (1 << 12) : 0); @@ -2727,8 +2264,7 @@ int patch_alc655(struct snd_ac97 * ac97) if (ac97->subsystem_vendor == 0x1462 && (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ ac97->subsystem_device == 0x0161 || /* LG K1 Express */ - ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ - ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ + ac97->subsystem_device == 0x0351)) /* MSI L725 laptop */ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ else val |= (1 << 1); /* Pin 47 is spdif input pin */ @@ -2761,16 +2297,16 @@ static void alc850_update_jacks(struct snd_ac97 *ac97) { int shared; - /* shared Line-In / Surround Out */ - shared = is_shared_surrout(ac97); + /* shared Line-In */ + shared = is_shared_linein(ac97); /* SURR 1kOhm (bit4), Amp (bit5) */ snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5), shared ? (1<<5) : (1<<4)); /* LINE-IN = 0, SURROUND = 2 */ snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, shared ? (2<<12) : (0<<12)); - /* update shared Mic In / Center/LFE Out */ - shared = is_shared_clfeout(ac97); + /* update shared mic */ + shared = is_shared_micin(ac97); /* Vref disable (bit12), 1kOhm (bit13) */ snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), shared ? (1<<12) : (1<<13)); @@ -2843,9 +2379,9 @@ int patch_alc850(struct snd_ac97 *ac97) */ static void cm9738_update_jacks(struct snd_ac97 *ac97) { - /* shared Line-In / Surround Out */ + /* shared Line-In */ snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10, - is_shared_surrout(ac97) ? (1 << 10) : 0); + is_shared_linein(ac97) ? (1 << 10) : 0); } static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = { @@ -2927,12 +2463,12 @@ static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = { static void cm9739_update_jacks(struct snd_ac97 *ac97) { - /* shared Line-In / Surround Out */ + /* shared Line-In */ snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10, - is_shared_surrout(ac97) ? (1 << 10) : 0); - /* shared Mic In / Center/LFE Out **/ + is_shared_linein(ac97) ? (1 << 10) : 0); + /* shared Mic */ snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, - is_shared_clfeout(ac97) ? 0x1000 : 0x2000); + is_shared_micin(ac97) ? 0x1000 : 0x2000); } static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = { @@ -3044,8 +2580,8 @@ static void cm9761_update_jacks(struct snd_ac97 *ac97) val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)]; val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)]; - val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)]; - val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)]; + val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)]; + val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)]; snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val); } @@ -3285,7 +2821,6 @@ int patch_vt1617a(struct snd_ac97 * ac97) 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; } @@ -3293,12 +2828,12 @@ int patch_vt1617a(struct snd_ac97 * ac97) */ static void it2646_update_jacks(struct snd_ac97 *ac97) { - /* shared Line-In / Surround Out */ + /* shared Line-In */ snd_ac97_update_bits(ac97, 0x76, 1 << 9, - is_shared_surrout(ac97) ? (1<<9) : 0); - /* shared Mic / Center/LFE Out */ + is_shared_linein(ac97) ? (1<<9) : 0); + /* shared Mic */ snd_ac97_update_bits(ac97, 0x76, 1 << 10, - is_shared_clfeout(ac97) ? (1<<10) : 0); + is_shared_micin(ac97) ? (1<<10) : 0); } static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = { diff --git a/trunk/sound/pci/ac97/ac97_patch.h b/trunk/sound/pci/ac97/ac97_patch.h index 94340daaaf1f..741979217207 100644 --- a/trunk/sound/pci/ac97/ac97_patch.h +++ b/trunk/sound/pci/ac97/ac97_patch.h @@ -48,7 +48,6 @@ 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); diff --git a/trunk/sound/pci/ac97/ak4531_codec.c b/trunk/sound/pci/ac97/ak4531_codec.c index dc26820a03a5..c153cb79c518 100644 --- a/trunk/sound/pci/ac97/ak4531_codec.c +++ b/trunk/sound/pci/ac97/ak4531_codec.c @@ -267,9 +267,9 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); +static DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); +static DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); +static DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); static struct snd_kcontrol_new snd_ak4531_controls[] = { diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 8afcb98ca7bb..9f406fbe0d95 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -444,7 +444,7 @@ static int snd_als300_capture_close(struct snd_pcm_substream *substream) } static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + snd_pcm_hw_params_t * hw_params) { return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); @@ -673,7 +673,7 @@ static void snd_als300_init(struct snd_als300 *chip) snd_als300_dbgcallleave(); } -static int __devinit snd_als300_create(struct snd_card *card, +static int __devinit snd_als300_create(snd_card_t *card, struct pci_dev *pci, int chip_type, struct snd_als300 **rchip) { @@ -681,7 +681,7 @@ static int __devinit snd_als300_create(struct snd_card *card, void *irq_handler; int err; - static struct snd_device_ops ops = { + static snd_device_ops_t ops = { .dev_free = snd_als300_dev_free, }; *rchip = NULL; diff --git a/trunk/sound/pci/atiixp.c b/trunk/sound/pci/atiixp.c index 7d8053b5e8d5..476c3433073e 100644 --- a/trunk/sound/pci/atiixp.c +++ b/trunk/sound/pci/atiixp.c @@ -45,7 +45,6 @@ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int ac97_clock = 48000; static char *ac97_quirk; static int spdif_aclink = 1; -static int ac97_codec = -1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); @@ -55,8 +54,6 @@ module_param(ac97_clock, int, 0444); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); module_param(ac97_quirk, charp, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); -module_param(ac97_codec, int, 0444); -MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing."); module_param(spdif_aclink, bool, 0444); MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); @@ -296,10 +293,6 @@ static struct pci_device_id snd_atiixp_ids[] = { MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); -static struct snd_pci_quirk atiixp_quirks[] __devinitdata = { - SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), - { } /* terminator */ -}; /* * lowlevel functions @@ -560,33 +553,11 @@ static int snd_atiixp_aclink_down(struct atiixp *chip) ATI_REG_ISR_CODEC2_NOT_READY) #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME) -static int ac97_probing_bugs(struct pci_dev *pci) -{ - const struct snd_pci_quirk *q; - - q = snd_pci_quirk_lookup(pci, atiixp_quirks); - if (q) { - snd_printdd(KERN_INFO "Atiixp quirk for %s. " - "Forcing codec %d\n", q->name, q->value); - return q->value; - } - /* this hardware doesn't need workarounds. Probe for codec */ - return -1; -} - static int snd_atiixp_codec_detect(struct atiixp *chip) { int timeout; chip->codec_not_ready_bits = 0; - if (ac97_codec == -1) - ac97_codec = ac97_probing_bugs(chip->pci); - if (ac97_codec >= 0) { - chip->codec_not_ready_bits |= - CODEC_CHECK_BITS ^ (1 << (ac97_codec + 10)); - return 0; - } - atiixp_write(chip, IER, CODEC_CHECK_BITS); /* wait for the interrupts */ timeout = 50; @@ -1425,7 +1396,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock, ac97.private_data = chip; ac97.pci = chip->pci; ac97.num = i; - ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_MODEM; if (! chip->spdif_over_aclink) ac97.scaps |= AC97_SCAP_NO_SPDIF; if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { diff --git a/trunk/sound/pci/atiixp_modem.c b/trunk/sound/pci/atiixp_modem.c index 904023fe4f26..cc2e6b9d407e 100644 --- a/trunk/sound/pci/atiixp_modem.c +++ b/trunk/sound/pci/atiixp_modem.c @@ -1090,7 +1090,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock) ac97.private_data = chip; ac97.pci = chip->pci; ac97.num = i; - ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_AUDIO; if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { chip->ac97[i] = NULL; /* to be sure */ snd_printdd("atiixp-modem: codec %d not available for modem\n", i); diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index ea6712b63c9f..f61f052f6d14 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -1382,6 +1382,7 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ chip->spdif_enable = 0; /* Set digital SPDIF output off */ + chip->capture_source = 3; /* Set CAPTURE_SOURCE */ //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */ @@ -1401,22 +1402,8 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card, snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */ snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */ } - if (chip->details->i2c_adc == 1) { - /* Select MIC, Line in, TAD in, AUX in */ - snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); - /* Default to CAPTURE_SOURCE to i2s in */ - chip->capture_source = 3; - } else if (chip->details->ac97 == 1) { - /* Default to AC97 in */ - snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4); - /* Default to CAPTURE_SOURCE to AC97 in */ - chip->capture_source = 4; - } else { - /* Select MIC, Line in, TAD in, AUX in */ - snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); - /* Default to Set CAPTURE_SOURCE to i2s in */ - chip->capture_source = 3; - } + snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ + chip->capture_source = 3; /* Set CAPTURE_SOURCE */ if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ @@ -1618,8 +1605,6 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, snd_ca0106_proc_init(chip); #endif - snd_card_set_dev(card, &pci->dev); - if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; diff --git a/trunk/sound/pci/ca0106/ca0106_mixer.c b/trunk/sound/pci/ca0106/ca0106_mixer.c index b913a1fb8c21..9855f528ea78 100644 --- a/trunk/sound/pci/ca0106/ca0106_mixer.c +++ b/trunk/sound/pci/ca0106/ca0106_mixer.c @@ -74,8 +74,8 @@ #include "ca0106.h" -static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); -static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); +static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); +static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -482,6 +482,19 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol, .private_value = ((chid) << 8) | (reg) \ } +#define I2C_VOLUME(xname,chid) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ + .info = snd_ca0106_i2c_volume_info, \ + .get = snd_ca0106_i2c_volume_get, \ + .put = snd_ca0106_i2c_volume_put, \ + .tlv = { .p = snd_ca0106_db_scale2 }, \ + .private_value = chid \ +} + + static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { CA_VOLUME("Analog Front Playback Volume", CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2), @@ -504,6 +517,11 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { CA_VOLUME("CAPTURE feedback Playback Volume", 1, CAPTURE_CONTROL), + I2C_VOLUME("Phone Capture Volume", 0), + I2C_VOLUME("Mic Capture Volume", 1), + I2C_VOLUME("Line in Capture Volume", 2), + I2C_VOLUME("Aux Capture Volume", 3), + { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -521,14 +539,14 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Digital Source Capture Enum", + .name = "Digital Capture Source", .info = snd_ca0106_capture_source_info, .get = snd_ca0106_capture_source_get, .put = snd_ca0106_capture_source_put }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Source Capture Enum", + .name = "Capture Source", .info = snd_ca0106_i2c_capture_source_info, .get = snd_ca0106_i2c_capture_source_get, .put = snd_ca0106_i2c_capture_source_put @@ -543,25 +561,6 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { }, }; -#define I2C_VOLUME(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ - SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .info = snd_ca0106_i2c_volume_info, \ - .get = snd_ca0106_i2c_volume_get, \ - .put = snd_ca0106_i2c_volume_put, \ - .tlv = { .p = snd_ca0106_db_scale2 }, \ - .private_value = chid \ -} - -static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = { - I2C_VOLUME("Phone Capture Volume", 0), - I2C_VOLUME("Mic Capture Volume", 1), - I2C_VOLUME("Line in Capture Volume", 2), - I2C_VOLUME("Aux Capture Volume", 3), -}; - static int __devinit remove_ctl(struct snd_card *card, const char *name) { struct snd_ctl_elem_id id; @@ -646,11 +645,6 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu) return err; } if (emu->details->i2c_adc == 1) { - for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_i2c_adc_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_i2c_adc_ctls[i], emu)); - if (err < 0) - return err; - } if (emu->details->gpio_type == 1) err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); else /* gpio_type == 2 */ diff --git a/trunk/sound/pci/cs4281.c b/trunk/sound/pci/cs4281.c index 44cf54607647..8e5519de7115 100644 --- a/trunk/sound/pci/cs4281.c +++ b/trunk/sound/pci/cs4281.c @@ -1055,7 +1055,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol, return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); static struct snd_kcontrol_new snd_cs4281_fm_vol = { diff --git a/trunk/sound/pci/echoaudio/darla20.c b/trunk/sound/pci/echoaudio/darla20.c index 8e7fe033270f..b7108e29a668 100644 --- a/trunk/sound/pci/echoaudio/darla20.c +++ b/trunk/sound/pci/echoaudio/darla20.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/darla24.c b/trunk/sound/pci/echoaudio/darla24.c index a13c623eb999..e59a982ee361 100644 --- a/trunk/sound/pci/echoaudio/darla24.c +++ b/trunk/sound/pci/echoaudio/darla24.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/echo3g.c b/trunk/sound/pci/echoaudio/echo3g.c index 8fb15823aca5..12099fe1547d 100644 --- a/trunk/sound/pci/echoaudio/echo3g.c +++ b/trunk/sound/pci/echoaudio/echo3g.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/echo3g_dsp.c b/trunk/sound/pci/echoaudio/echo3g_dsp.c index 48eb7c599111..d26a1d1f3ed1 100644 --- a/trunk/sound/pci/echoaudio/echo3g_dsp.c +++ b/trunk/sound/pci/echoaudio/echo3g_dsp.c @@ -39,7 +39,7 @@ static int set_phantom_power(struct echoaudio *chip, char on); static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, char force); -#include +#include static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) { diff --git a/trunk/sound/pci/echoaudio/echoaudio.c b/trunk/sound/pci/echoaudio/echoaudio.c index 6a428b81dba6..047e0b5bf15d 100644 --- a/trunk/sound/pci/echoaudio/echoaudio.c +++ b/trunk/sound/pci/echoaudio/echoaudio.c @@ -34,7 +34,6 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; -static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); static int get_firmware(const struct firmware **fw_entry, const struct firmware *frm, struct echoaudio *chip) @@ -1012,21 +1011,17 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { .name = "Line Playback Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .info = snd_echo_output_gain_info, .get = snd_echo_output_gain_get, .put = snd_echo_output_gain_put, - .tlv = {.p = db_scale_output_gain}, }; #else static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { .name = "PCM Playback Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .info = snd_echo_output_gain_info, .get = snd_echo_output_gain_get, .put = snd_echo_output_gain_put, - .tlv = {.p = db_scale_output_gain}, }; #endif @@ -1085,16 +1080,12 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, return changed; } -static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); - static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { .name = "Line Capture Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .info = snd_echo_input_gain_info, .get = snd_echo_input_gain_get, .put = snd_echo_input_gain_put, - .tlv = {.p = db_scale_input_gain}, }; #endif /* ECHOCARD_HAS_INPUT_GAIN */ @@ -1286,11 +1277,9 @@ static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { .name = "Monitor Mixer Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .info = snd_echo_mixer_info, .get = snd_echo_mixer_get, .put = snd_echo_mixer_put, - .tlv = {.p = db_scale_output_gain}, }; #endif /* ECHOCARD_HAS_MONITOR */ @@ -1354,11 +1343,9 @@ static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { .name = "VMixer Volume", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, .info = snd_echo_vmixer_info, .get = snd_echo_vmixer_get, .put = snd_echo_vmixer_put, - .tlv = {.p = db_scale_output_gain}, }; #endif /* ECHOCARD_HAS_VMIXER */ @@ -1766,12 +1753,9 @@ static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { .name = "VU-meters", .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_echo_vumeters_info, .get = snd_echo_vumeters_get, - .tlv = {.p = db_scale_output_gain}, }; diff --git a/trunk/sound/pci/echoaudio/gina20.c b/trunk/sound/pci/echoaudio/gina20.c index af4d32026e4a..29d6d12f80ca 100644 --- a/trunk/sound/pci/echoaudio/gina20.c +++ b/trunk/sound/pci/echoaudio/gina20.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/gina24.c b/trunk/sound/pci/echoaudio/gina24.c index 9ff454a947ed..e464d720d0bd 100644 --- a/trunk/sound/pci/echoaudio/gina24.c +++ b/trunk/sound/pci/echoaudio/gina24.c @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/indigo.c b/trunk/sound/pci/echoaudio/indigo.c index 37eb726fd03d..bfd2467099ac 100644 --- a/trunk/sound/pci/echoaudio/indigo.c +++ b/trunk/sound/pci/echoaudio/indigo.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/indigodj.c b/trunk/sound/pci/echoaudio/indigodj.c index dc8b91824181..8ed7ff1fd875 100644 --- a/trunk/sound/pci/echoaudio/indigodj.c +++ b/trunk/sound/pci/echoaudio/indigodj.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/indigoio.c b/trunk/sound/pci/echoaudio/indigoio.c index eadf3263453a..a8788e959171 100644 --- a/trunk/sound/pci/echoaudio/indigoio.c +++ b/trunk/sound/pci/echoaudio/indigoio.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/layla20.c b/trunk/sound/pci/echoaudio/layla20.c index 6cede497579e..e503d74b3ba9 100644 --- a/trunk/sound/pci/echoaudio/layla20.c +++ b/trunk/sound/pci/echoaudio/layla20.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/layla24.c b/trunk/sound/pci/echoaudio/layla24.c index 44f735426aa0..d4581fdc841c 100644 --- a/trunk/sound/pci/echoaudio/layla24.c +++ b/trunk/sound/pci/echoaudio/layla24.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/mia.c b/trunk/sound/pci/echoaudio/mia.c index dc172d03ac3f..be40c64263d2 100644 --- a/trunk/sound/pci/echoaudio/mia.c +++ b/trunk/sound/pci/echoaudio/mia.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/echoaudio/mona.c b/trunk/sound/pci/echoaudio/mona.c index c856ed50dd9a..5dc512add372 100644 --- a/trunk/sound/pci/echoaudio/mona.c +++ b/trunk/sound/pci/echoaudio/mona.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 80aa585eade4..972ec40d8166 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -3,10 +3,8 @@ * Creative Labs, Inc. * Routines for control of EMU10K1 chips * - * Copyright (c) by James Courtier-Dutton + * Copyright (c) by James Courtier-Dutton * Added support for Audigy 2 Value. - * Added EMU 1010 support. - * General bug fixes and enhancements. * * * BUGS: @@ -43,10 +41,8 @@ #include #include -#include #include "p16v.h" #include "tina2.h" -#include "p17v.h" /************************************************************************* @@ -121,28 +117,11 @@ static unsigned int spi_dac_init[] = { 0x0622, 0x1400, }; - -static unsigned int i2c_adc_init[][2] = { - { 0x17, 0x00 }, /* Reset */ - { 0x07, 0x00 }, /* Timeout */ - { 0x0b, 0x22 }, /* Interface control */ - { 0x0c, 0x22 }, /* Master mode control */ - { 0x0d, 0x08 }, /* Powerdown control */ - { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */ - { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */ - { 0x10, 0x7b }, /* ALC Control 1 */ - { 0x11, 0x00 }, /* ALC Control 2 */ - { 0x12, 0x32 }, /* ALC Control 3 */ - { 0x13, 0x00 }, /* Noise gate control */ - { 0x14, 0xa6 }, /* Limiter control */ - { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for Audigy 2 ZS Notebook */ -}; static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) { unsigned int silent_page; int ch; - u32 tmp; /* disable audio and lock cache */ outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, @@ -181,6 +160,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ /* Hacks for Alice3 to work independent of haP16V driver */ + u32 tmp; + //Setup SRCMulti_I2S SamplingRate tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); tmp &= 0xfffff1ff; @@ -200,6 +181,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) } if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ /* Hacks for Alice3 to work independent of haP16V driver */ + u32 tmp; + snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); //Setup SRCMulti_I2S SamplingRate tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); @@ -228,7 +211,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) int size, n; size = ARRAY_SIZE(spi_dac_init); - for (n = 0; n < size; n++) + for (n=0; n < size; n++) snd_emu10k1_spi_write(emu, spi_dac_init[n]); snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10); @@ -245,23 +228,6 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */ } - if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */ - int size, n; - - snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f); - tmp = inl(emu->port + A_IOCFG); - outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */ - tmp = inl(emu->port + A_IOCFG); - size = ARRAY_SIZE(i2c_adc_init); - for (n = 0; n < size; n++) - snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); - for (n=0; n < 4; n++) { - emu->i2c_capture_volume[n][0]= 0xcf; - emu->i2c_capture_volume[n][1]= 0xcf; - } - - } - snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ @@ -273,10 +239,6 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); } - if (emu->card_capabilities->emu1010) { - outl(HCFG_AUTOMUTE_ASYNC | - HCFG_EMU32_SLAVE | - HCFG_AUDIOENABLE, emu->port + HCFG); /* * Hokay, setup HCFG * Mute Disable Audio = 0 @@ -284,7 +246,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) * Lock Sound Memory = 0 * Auto Mute = 1 */ - } else if (emu->audigy) { + if (emu->audigy) { if (emu->revision == 4) /* audigy2 */ outl(HCFG_AUDIOENABLE | HCFG_AC3ENABLE_CDSPDIF | @@ -303,10 +265,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); if (enable_ir) { /* enable IR for SB Live */ - if (emu->card_capabilities->emu1010) { - ; /* Disable all access to A_IOCFG for the emu1010 */ - } else if (emu->card_capabilities->i2c_adc) { - ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ + if ( emu->card_capabilities->emu1212m) { + ; /* Disable all access to A_IOCFG for the emu1212m */ } else if (emu->audigy) { unsigned int reg = inl(emu->port + A_IOCFG); outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); @@ -324,10 +284,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) } } - if (emu->card_capabilities->emu1010) { - ; /* Disable all access to A_IOCFG for the emu1010 */ - } else if (emu->card_capabilities->i2c_adc) { - ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ + if ( emu->card_capabilities->emu1212m) { + ; /* Disable all access to A_IOCFG for the emu1212m */ } else if (emu->audigy) { /* enable analog output */ unsigned int reg = inl(emu->port + A_IOCFG); outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); @@ -344,10 +302,8 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); /* Enable analog/digital outs on audigy */ - if (emu->card_capabilities->emu1010) { - ; /* Disable all access to A_IOCFG for the emu1010 */ - } else if (emu->card_capabilities->i2c_adc) { - ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ + if ( emu->card_capabilities->emu1212m) { + ; /* Disable all access to A_IOCFG for the emu1212m */ } else if (emu->audigy) { outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); @@ -640,423 +596,133 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) return 0; } -static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename) +static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value) { - int err; - int n, i; - int reg; - int value; - const struct firmware *fw_entry; - - if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { - snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); - return err; - } - snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); - if (fw_entry->size != 0x133a4) { - snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); - return -EINVAL; - } + if (reg<0 || reg>0x3f) + return 1; + reg+=0x40; /* 0x40 upwards are registers. */ + if (value<0 || value>0x3f) /* 0 to 0x3f are values */ + return 1; + outl(reg, emu->port + A_IOCFG); + outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ + outl(value, emu->port + A_IOCFG); + outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - /* The FPGA is a Xilinx Spartan IIE XC2S50E */ - /* GPIO7 -> FPGA PGMN - * GPIO6 -> FPGA CCLK - * GPIO5 -> FPGA DIN - * FPGA CONFIG OFF -> FPGA PGMN - */ - outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */ - udelay(1); - outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ - udelay(100); /* Allow FPGA memory to clean */ - for(n = 0; n < fw_entry->size; n++) { - value=fw_entry->data[n]; - for(i = 0; i < 8; i++) { - reg = 0x80; - if (value & 0x1) - reg = reg | 0x20; - value = value >> 1; - outl(reg, emu->port + A_IOCFG); - outl(reg | 0x40, emu->port + A_IOCFG); - } - } - /* After programming, set GPIO bit 4 high again. */ - outl(0x10, emu->port + A_IOCFG); - + return 0; +} + +static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) +{ + if (reg<0 || reg>0x3f) + return 1; + reg+=0x40; /* 0x40 upwards are registers. */ + outl(reg, emu->port + A_IOCFG); + outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ + *value = inl(emu->port + A_IOCFG); - release_firmware(fw_entry); return 0; } -static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) +static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value) +{ + snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) ); + snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) ); + snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) ); + snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) ); + + return 0; +} + +static int snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu) { unsigned int i; - 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, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Mute all codecs. - */ + int tmp; + + snd_printk(KERN_ERR "emu1212m: Special config.\n"); outl(0x0005a00c, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Lock Tank Memory Cache, - * Mute all codecs. - */ - outl(0x0005a004, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Mute all codecs. - */ + outl(0x0005a004, emu->port + HCFG); outl(0x0005a000, emu->port + HCFG); - /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, - * Mute all codecs. - */ outl(0x0005a000, emu->port + HCFG); - /* Disable 48Volt power to Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); - - /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ - snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - snd_printdd("reg1=0x%x\n",reg); - if (reg == 0x55) { - /* FPGA netlist already present so clear it */ - /* Return to programming mode */ - - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 ); + snd_emu1212m_fpga_read(emu, 0x22, &tmp ); + snd_emu1212m_fpga_read(emu, 0x23, &tmp ); + snd_emu1212m_fpga_read(emu, 0x24, &tmp ); + snd_emu1212m_fpga_write(emu, 0x04, 0x01 ); + snd_emu1212m_fpga_read(emu, 0x0b, &tmp ); + snd_emu1212m_fpga_write(emu, 0x0b, 0x01 ); + snd_emu1212m_fpga_read(emu, 0x10, &tmp ); + snd_emu1212m_fpga_write(emu, 0x10, 0x00 ); + snd_emu1212m_fpga_read(emu, 0x11, &tmp ); + snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); + snd_emu1212m_fpga_read(emu, 0x13, &tmp ); + snd_emu1212m_fpga_write(emu, 0x13, 0x0f ); + snd_emu1212m_fpga_read(emu, 0x11, &tmp ); + snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); + snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); + snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); + snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); + snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); + snd_emu1212m_fpga_write(emu, 0x09, 0x0f ); + snd_emu1212m_fpga_write(emu, 0x06, 0x00 ); + snd_emu1212m_fpga_write(emu, 0x05, 0x00 ); + snd_emu1212m_fpga_write(emu, 0x0e, 0x12 ); + snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200); + snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201); + snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500); + snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501); + snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400); + snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401); + snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402); + snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403); + snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404); + snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405); + snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406); + snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407); + snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100); + snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104); + snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200); + snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201); + for (i=0;i < 0x20;i++) { + snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000); } - snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - snd_printdd("reg2=0x%x\n",reg); - if (reg == 0x55) { - /* FPGA failed to return to programming mode */ - return -ENODEV; + for (i=0;i < 4;i++) { + snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000); } - 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); - return err; + for (i=0;i < 7;i++) { + snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000); } - - /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ - snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - if (reg != 0x55) { - /* FPGA failed to be programmed */ - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); - return -ENODEV; + for (i=0;i < 7;i++) { + snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000); } + snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108); + snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c); + snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110); + snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114); + snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118); + snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c); + snd_emu1212m_fpga_write(emu, 0x07, 0x01 ); - snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); - snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp ); - snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 ); - snd_printk("Hana ver:%d.%d\n",tmp ,tmp2); - /* Enable 48Volt power to Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON ); - - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); - snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); - snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); - snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); - /* ADAT input. */ - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 ); - snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp ); - /* Set no attenuation on Audio Dock pads. */ - snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 ); - emu->emu1010.adc_pads = 0x00; - snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); - /* Unmute Audio dock DACs, Headphone source DAC-4. */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); - snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp ); - /* DAC PADs. */ - snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f ); - emu->emu1010.dac_pads = 0x0f; - snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); - snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); - /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ - snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); - /* MIDI routing */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); - /* Unknown. */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); - /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */ - /* IRQ Enable: All off */ - snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 ); - - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); - snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg); - /* Default WCLK set to 48kHz. */ - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 ); - /* Word Clock source, Internal 48kHz x1 */ - snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); - //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); - /* Audio Dock LEDs. */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); + snd_emu1212m_fpga_read(emu, 0x21, &tmp ); -#if 0 - /* For 96kHz */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2); -#endif -#if 0 - /* For 192kHz */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4); -#endif -#if 1 - /* For 48kHz */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); -#endif -#if 0 - /* Original */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); -#endif - for (i = 0;i < 0x20; i++ ) { - /* AudioDock Elink <- Silence */ - snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE); - } - for (i = 0;i < 4; i++) { - /* Hana SPDIF Out <- Silence */ - snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE); - } - for (i = 0;i < 7; i++) { - /* Hamoa DAC <- Silence */ - snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE); - } - for (i = 0;i < 7; i++) { - /* Hana ADAT Out <- Silence */ - snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); - } - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all - - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); - - /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Mute all codecs. - */ - outl(0x0000a000, emu->port + HCFG); - /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, - * Lock Sound Memory Cache, Lock Tank Memory Cache, - * Un-Mute all codecs. - */ + outl(0x0000a000, emu->port + HCFG); outl(0x0000a001, emu->port + HCFG); - /* Initial boot complete. Now patches */ - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ - snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ - snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); - snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ - - /* Delay to allow Audio Dock to settle */ - msleep(100); - snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ - snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); /* OPTIONS: Which cards are attached to the EMU */ - /* FIXME: The loading of this should be able to happen any time, - * as the user can plug/unplug it at any time - */ - if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) { - /* Audio Dock attached */ - /* 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) { - return err; - } - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); - snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); - snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); - /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ - snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); - if (reg != 0x55) { - /* FPGA failed to be programmed */ - snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); - return 0; - return -ENODEV; - } - snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); - snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); - snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); - snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); - } -#if 0 - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */ -#endif - /* Default outputs */ - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[0] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[1] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2); - emu->emu1010.output_source[2] = 23; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); - emu->emu1010.output_source[3] = 24; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4); - emu->emu1010.output_source[4] = 25; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5); - emu->emu1010.output_source[5] = 26; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6); - emu->emu1010.output_source[6] = 27; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7); - emu->emu1010.output_source[7] = 28; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[8] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[9] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[10] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[11] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[12] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[13] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[14] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[15] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */ - emu->emu1010.output_source[16] = 21; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1); - emu->emu1010.output_source[17] = 22; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2); - emu->emu1010.output_source[18] = 23; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3); - emu->emu1010.output_source[19] = 24; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4); - emu->emu1010.output_source[20] = 25; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5); - emu->emu1010.output_source[21] = 26; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6); - emu->emu1010.output_source[22] = 27; - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7); - emu->emu1010.output_source[23] = 28; - - /* TEMP: Select SPDIF in/out */ - snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ - - /* TEMP: Select 48kHz SPDIF out */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ - /* Word Clock source, Internal 48kHz x1 */ - snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); - //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); - emu->emu1010.internal_clock = 1; /* 48000 */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ - //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ - //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */ - //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */ + snd_emu1212m_fpga_read(emu, 0x21, &tmp ); + snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); + snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); + snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); + snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); + snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); + snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); + + snd_emu1212m_fpga_read(emu, 0x20, &tmp ); + snd_emu1212m_fpga_read(emu, 0x21, &tmp ); + + snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312); + snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313); + snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302); + snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303); return 0; } @@ -1081,10 +747,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) } snd_emu10k1_free_efx(emu); } - if (emu->card_capabilities->emu1010) { - /* Disable 48Volt power to Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); - } if (emu->memhdr) snd_util_memhdr_free(emu->memhdr); if (emu->silent_page.area) @@ -1176,11 +838,10 @@ static struct snd_emu_chip_details emu_chip_details[] = { .adc_1361t = 1, /* 24 bit capture instead of 16bit */ .ac97_chip = 1} , /* Audigy 2 ZS Notebook Cardbus card.*/ - /* Tested by James@superbug.co.uk 6th November 2006 */ + /* Tested by James@superbug.co.uk 22th December 2005 */ /* Audio output 7.1/Headphones working. * Digital output working. (AC3 not checked, only PCM) - * Audio Mic/Line inputs working. - * Digital input not tested. + * Audio inputs not tested. */ /* DSP: Tina2 * DAC: Wolfson WM8768/WM8568 @@ -1188,25 +849,6 @@ static struct snd_emu_chip_details emu_chip_details[] = { * AC97: None * CA0151: None */ - /* Tested by James@superbug.co.uk 4th April 2006 */ - /* A_IOCFG bits - * Output - * 0: Not Used - * 1: 0 = Mute all the 7.1 channel out. 1 = unmute. - * 2: Analog input 0 = line in, 1 = mic in - * 3: Not Used - * 4: Digital output 0 = off, 1 = on. - * 5: Not Used - * 6: Not Used - * 7: Not Used - * Input - * All bits 1 (0x3fxx) means nothing plugged in. - * 8-9: 0 = Line in/Mic, 2 = Optical in, 3 = Nothing. - * A-B: 0 = Headphones, 2 = Optical out, 3 = Nothing. - * C-D: 2 = Front/Rear/etc, 3 = nothing. - * E-F: Always 0 - * - */ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", .id = "Audigy2", @@ -1214,7 +856,6 @@ static struct snd_emu_chip_details emu_chip_details[] = { .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]", @@ -1224,12 +865,11 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ac97_chip = 1} , /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, - .driver = "Audigy2", .name = "E-mu 1010 [4001]", - .id = "EMU1010", + .driver = "Audigy2", .name = "E-mu 1212m [4001]", + .id = "EMU1212m", .emu10k2_chip = 1, .ca0102_chip = 1, - .spk71 = 1, - .emu1010 = 1} , + .emu1212m = 1} , /* Tested by James@superbug.co.uk 3rd July 2005 */ {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", @@ -1657,8 +1297,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card, } else if (emu->card_capabilities->ca_cardbus_chip) { if ((err = snd_emu10k1_cardbus_init(emu)) < 0) goto error; - } else if (emu->card_capabilities->emu1010) { - if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { + } else if (emu->card_capabilities->emu1212m) { + if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) { snd_emu10k1_free(emu); return err; } @@ -1806,8 +1446,8 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) snd_emu10k1_ecard_init(emu); else if (emu->card_capabilities->ca_cardbus_chip) snd_emu10k1_cardbus_init(emu); - else if (emu->card_capabilities->emu1010) - snd_emu10k1_emu1010_init(emu); + else if (emu->card_capabilities->emu1212m) + snd_emu10k1_emu1212m_init(emu); else snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); snd_emu10k1_init(emu, emu->enable_ir, 1); diff --git a/trunk/sound/pci/emu10k1/emu10k1x.c b/trunk/sound/pci/emu10k1/emu10k1x.c index bb0fec7f7e1b..2199b42a6019 100644 --- a/trunk/sound/pci/emu10k1/emu10k1x.c +++ b/trunk/sound/pci/emu10k1/emu10k1x.c @@ -460,7 +460,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream) u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); int i; - for(i = 0; i < runtime->periods; i++) { + for(i=0; i < runtime->periods; i++) { *table_base++=runtime->dma_addr+(i*period_size_bytes); *table_base++=period_size_bytes<<16; } @@ -1042,8 +1042,8 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) continue; - if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff) - && (channel_id >= 0) && (channel_id <= 2) ) + if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff) + && (channel_id >=0) && (channel_id <= 2) ) snd_emu10k1x_ptr_write(emu, reg, channel_id, val); } } diff --git a/trunk/sound/pci/emu10k1/emufx.c b/trunk/sound/pci/emu10k1/emufx.c index c02012cccd8e..13cd6ce89811 100644 --- a/trunk/sound/pci/emu10k1/emufx.c +++ b/trunk/sound/pci/emu10k1/emufx.c @@ -3,9 +3,6 @@ * Creative Labs, Inc. * Routines for effect processor FX8010 * - * Copyright (c) by James Courtier-Dutton - * Added EMU 1010 support. - * * BUGS: * -- * @@ -296,7 +293,7 @@ static const u32 db_table[101] = { }; /* EMU10k1/EMU10k2 DSP control db gain */ -static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); +static DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); static const u32 onoff_table[2] = { 0x00000000, 0x00000001 @@ -655,66 +652,13 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id) return NULL; } -#define MAX_TLV_SIZE 256 - -static unsigned int *copy_tlv(const unsigned int __user *_tlv) -{ - unsigned int data[2]; - unsigned int *tlv; - - if (!_tlv) - return NULL; - if (copy_from_user(data, _tlv, sizeof(data))) - return NULL; - if (data[1] >= MAX_TLV_SIZE) - return NULL; - tlv = kmalloc(data[1] * 4 + sizeof(data), GFP_KERNEL); - if (!tlv) - return NULL; - memcpy(tlv, data, sizeof(data)); - if (copy_from_user(tlv + 2, _tlv + 2, data[1])) { - kfree(tlv); - return NULL; - } - return tlv; -} - -static int copy_gctl(struct snd_emu10k1 *emu, - struct snd_emu10k1_fx8010_control_gpr *gctl, - struct snd_emu10k1_fx8010_control_gpr __user *_gctl, - int idx) -{ - struct snd_emu10k1_fx8010_control_old_gpr __user *octl; - - if (emu->support_tlv) - return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)); - octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; - if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) - return -EFAULT; - gctl->tlv = NULL; - return 0; -} - -static int copy_gctl_to_user(struct snd_emu10k1 *emu, - struct snd_emu10k1_fx8010_control_gpr __user *_gctl, - struct snd_emu10k1_fx8010_control_gpr *gctl, - int idx) -{ - struct snd_emu10k1_fx8010_control_old_gpr __user *octl; - - if (emu->support_tlv) - return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl)); - - octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; - return copy_to_user(&octl[idx], gctl, sizeof(*octl)); -} - static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_code *icode) { unsigned int i; struct snd_ctl_elem_id __user *_id; struct snd_ctl_elem_id id; + struct snd_emu10k1_fx8010_control_gpr __user *_gctl; struct snd_emu10k1_fx8010_control_gpr *gctl; int err; @@ -729,8 +673,9 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, if (! gctl) return -ENOMEM; err = 0; - for (i = 0; i < icode->gpr_add_control_count; i++) { - if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) { + for (i = 0, _gctl = icode->gpr_add_controls; + i < icode->gpr_add_control_count; i++, _gctl++) { + if (copy_from_user(gctl, _gctl, sizeof(*gctl))) { err = -EFAULT; goto __error; } @@ -749,9 +694,10 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, goto __error; } } - for (i = 0; i < icode->gpr_list_control_count; i++) { + for (i = 0, _gctl = icode->gpr_list_controls; + i < icode->gpr_list_control_count; i++, _gctl++) { /* FIXME: we need to check the WRITE access */ - if (copy_gctl(emu, gctl, icode->gpr_list_controls, i)) { + if (copy_from_user(gctl, _gctl, sizeof(*gctl))) { err = -EFAULT; goto __error; } @@ -769,14 +715,13 @@ static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl) kctl->private_value = 0; list_del(&ctl->list); kfree(ctl); - if (kctl->tlv.p) - kfree(kctl->tlv.p); } static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_code *icode) { unsigned int i, j; + struct snd_emu10k1_fx8010_control_gpr __user *_gctl; struct snd_emu10k1_fx8010_control_gpr *gctl; struct snd_emu10k1_fx8010_ctl *ctl, *nctl; struct snd_kcontrol_new knew; @@ -792,8 +737,9 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, goto __error; } - for (i = 0; i < icode->gpr_add_control_count; i++) { - if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) { + for (i = 0, _gctl = icode->gpr_add_controls; + i < icode->gpr_add_control_count; i++, _gctl++) { + if (copy_from_user(gctl, _gctl, sizeof(*gctl))) { err = -EFAULT; goto __error; } @@ -814,10 +760,11 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, knew.device = gctl->id.device; knew.subdevice = gctl->id.subdevice; knew.info = snd_emu10k1_gpr_ctl_info; - knew.tlv.p = copy_tlv(gctl->tlv); - if (knew.tlv.p) + if (gctl->tlv.p) { + knew.tlv.p = gctl->tlv.p; knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ; + } knew.get = snd_emu10k1_gpr_ctl_get; knew.put = snd_emu10k1_gpr_ctl_put; memset(nctl, 0, sizeof(*nctl)); @@ -835,14 +782,12 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); if (ctl == NULL) { err = -ENOMEM; - kfree(knew.tlv.p); goto __error; } knew.private_value = (unsigned long)ctl; *ctl = *nctl; if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) { kfree(ctl); - kfree(knew.tlv.p); goto __error; } kctl->private_free = snd_emu10k1_ctl_private_free; @@ -893,6 +838,7 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, unsigned int i = 0, j; unsigned int total = 0; struct snd_emu10k1_fx8010_control_gpr *gctl; + struct snd_emu10k1_fx8010_control_gpr __user *_gctl; struct snd_emu10k1_fx8010_ctl *ctl; struct snd_ctl_elem_id *id; struct list_head *list; @@ -901,11 +847,11 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, if (! gctl) return -ENOMEM; + _gctl = icode->gpr_list_controls; list_for_each(list, &emu->fx8010.gpr_ctl) { ctl = emu10k1_gpr_ctl(list); total++; - if (icode->gpr_list_controls && - i < icode->gpr_list_control_count) { + if (_gctl && i < icode->gpr_list_control_count) { memset(gctl, 0, sizeof(*gctl)); id = &ctl->kcontrol->id; gctl->id.iface = id->iface; @@ -922,11 +868,11 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, gctl->min = ctl->min; gctl->max = ctl->max; gctl->translation = ctl->translation; - if (copy_gctl_to_user(emu, icode->gpr_list_controls, - gctl, i)) { + if (copy_to_user(_gctl, gctl, sizeof(*gctl))) { kfree(gctl); return -EFAULT; } + _gctl++; i++; } } @@ -1077,7 +1023,7 @@ snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl, ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; ctl->min = 0; ctl->max = 100; - ctl->tlv = snd_emu10k1_db_scale1; + ctl->tlv.p = snd_emu10k1_db_scale1; ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; } @@ -1092,7 +1038,7 @@ snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl, ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; ctl->min = 0; ctl->max = 100; - ctl->tlv = snd_emu10k1_db_scale1; + ctl->tlv.p = snd_emu10k1_db_scale1; ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; } @@ -1123,21 +1069,6 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; } -static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( - struct snd_emu10k1_fx8010_code *icode, - u32 *ptr, int tmp, int bit_shifter16, - int reg_in, int reg_out) -{ - A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000); - A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000); - A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2)); - A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000); - A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000); - A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000); - A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2)); - A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000); - return 1; -} /* * initial DSP configuration for Audigy @@ -1146,7 +1077,6 @@ static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) { int err, i, z, gpr, nctl; - int bit_shifter16; const int playback = 10; const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ const int stereo_mix = capture + 2; @@ -1184,14 +1114,17 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) ptr = 0; nctl = 0; gpr = stereo_mix + 10; - gpr_map[gpr++] = 0x00007fff; - gpr_map[gpr++] = 0x00008000; - gpr_map[gpr++] = 0x0000ffff; - bit_shifter16 = gpr; /* stop FX processor */ snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); +#if 0 + /* FIX: jcd test */ + for (z = 0; z < 80; z=z+2) { + A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */ + A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */ + } +#endif /* jcd test */ #if 1 /* PCM front Playback Volume (independent from stereo mix) */ A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); @@ -1249,20 +1182,13 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); gpr += 2; - + /* * inputs */ #define A_ADD_VOLUME_IN(var,vol,input) \ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) - /* emu1212 DSP 0 and DSP 1 Capture */ - if (emu->card_capabilities->emu1010) { - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1)); - snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0); - gpr += 2; - } /* AC'97 Playback Volume - used only for mic (renamed later) */ A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); @@ -1503,13 +1429,6 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) /* digital outputs */ /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ - if (emu->card_capabilities->emu1010) { - /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */ - snd_printk("EMU outputs on\n"); - for (z = 0; z < 8; z++) { - A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); - } - } /* IEC958 Optical Raw Playback Switch */ gpr_map[gpr++] = 0; @@ -1547,57 +1466,9 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); #endif - if (emu->card_capabilities->emu1010) { - snd_printk("EMU inputs on\n"); - /* Capture 8 channels of S32_LE sound */ - - /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ - /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ - /* A_P16VIN(0) is delayed by one sample, - * so all other A_P16VIN channels will need to also be delayed - */ - /* Left ADC in. 1 of 2 */ - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); - /* Right ADC in 1 of 2 */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); - /* For 96kHz mode */ - /* Left ADC in. 2 of 2 */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); - /* Right ADC in 2 of 2 */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); - -#if 0 - for (z = 4; z < 8; z++) { - A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); - } - for (z = 0xc; z < 0x10; z++) { - A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); - } -#endif - } else { - /* EFX capture - capture the 16 EXTINs */ - /* Capture 16 channels of S16_LE sound */ - for (z = 0; z < 16; z++) { - A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); - } + /* EFX capture - capture the 16 EXTINs */ + for (z = 0; z < 16; z++) { + A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); } #endif /* JCD test */ @@ -1617,9 +1488,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) seg = snd_enter_user(); icode->gpr_add_control_count = nctl; icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; - emu->support_tlv = 1; /* support TLV */ err = snd_emu10k1_icode_poke(emu, icode); - emu->support_tlv = 0; /* clear again */ snd_leave_user(seg); __err: @@ -2236,9 +2105,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) seg = snd_enter_user(); icode->gpr_add_control_count = i; icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; - emu->support_tlv = 1; /* support TLV */ err = snd_emu10k1_icode_poke(emu, icode); - emu->support_tlv = 0; /* clear again */ snd_leave_user(seg); if (err >= 0) err = snd_emu10k1_ipcm_poke(emu, ipcm); @@ -2271,7 +2138,7 @@ void snd_emu10k1_free_efx(struct snd_emu10k1 *emu) snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); } -#if 0 /* FIXME: who use them? */ +#if 0 // FIXME: who use them? int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) { if (output < 0 || output >= 6) @@ -2382,9 +2249,6 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un int res; switch (cmd) { - case SNDRV_EMU10K1_IOCTL_PVERSION: - emu->support_tlv = 1; - return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp); case SNDRV_EMU10K1_IOCTL_INFO: info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) diff --git a/trunk/sound/pci/emu10k1/emumixer.c b/trunk/sound/pci/emu10k1/emumixer.c index 4db6e1ca1665..c31f3d0877fa 100644 --- a/trunk/sound/pci/emu10k1/emumixer.c +++ b/trunk/sound/pci/emu10k1/emumixer.c @@ -5,9 +5,6 @@ * Routines for control of EMU10K1 chips / mixer routines * Multichannel PCM support Copyright (c) Lee Revell * - * Copyright (c) by James Courtier-Dutton - * Added EMU 1010 support. - * * BUGS: * -- * @@ -35,15 +32,9 @@ #include #include #include -#include -#include - -#include "p17v.h" #define AC97_ID_STAC9758 0x83847658 -static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */ - static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; @@ -77,669 +68,6 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, return 0; } -static char *emu1010_src_texts[] = { - "Silence", - "Dock Mic A", - "Dock Mic B", - "Dock ADC1 Left", - "Dock ADC1 Right", - "Dock ADC2 Left", - "Dock ADC2 Right", - "Dock ADC3 Left", - "Dock ADC3 Right", - "0202 ADC Left", - "0202 ADC Right", - "0202 SPDIF Left", - "0202 SPDIF Right", - "ADAT 0", - "ADAT 1", - "ADAT 2", - "ADAT 3", - "ADAT 4", - "ADAT 5", - "ADAT 6", - "ADAT 7", - "DSP 0", - "DSP 1", - "DSP 2", - "DSP 3", - "DSP 4", - "DSP 5", - "DSP 6", - "DSP 7", - "DSP 8", - "DSP 9", - "DSP 10", - "DSP 11", - "DSP 12", - "DSP 13", - "DSP 14", - "DSP 15", - "DSP 16", - "DSP 17", - "DSP 18", - "DSP 19", - "DSP 20", - "DSP 21", - "DSP 22", - "DSP 23", - "DSP 24", - "DSP 25", - "DSP 26", - "DSP 27", - "DSP 28", - "DSP 29", - "DSP 30", - "DSP 31", -}; - -static unsigned int emu1010_src_regs[] = { - EMU_SRC_SILENCE,/* 0 */ - EMU_SRC_DOCK_MIC_A1, /* 1 */ - EMU_SRC_DOCK_MIC_B1, /* 2 */ - EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */ - EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */ - EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */ - EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */ - EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */ - EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */ - EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */ - EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */ - EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */ - EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */ - EMU_SRC_HANA_ADAT, /* 13 */ - EMU_SRC_HANA_ADAT+1, /* 14 */ - EMU_SRC_HANA_ADAT+2, /* 15 */ - EMU_SRC_HANA_ADAT+3, /* 16 */ - EMU_SRC_HANA_ADAT+4, /* 17 */ - EMU_SRC_HANA_ADAT+5, /* 18 */ - EMU_SRC_HANA_ADAT+6, /* 19 */ - EMU_SRC_HANA_ADAT+7, /* 20 */ - EMU_SRC_ALICE_EMU32A, /* 21 */ - EMU_SRC_ALICE_EMU32A+1, /* 22 */ - EMU_SRC_ALICE_EMU32A+2, /* 23 */ - EMU_SRC_ALICE_EMU32A+3, /* 24 */ - EMU_SRC_ALICE_EMU32A+4, /* 25 */ - EMU_SRC_ALICE_EMU32A+5, /* 26 */ - EMU_SRC_ALICE_EMU32A+6, /* 27 */ - EMU_SRC_ALICE_EMU32A+7, /* 28 */ - EMU_SRC_ALICE_EMU32A+8, /* 29 */ - EMU_SRC_ALICE_EMU32A+9, /* 30 */ - EMU_SRC_ALICE_EMU32A+0xa, /* 31 */ - EMU_SRC_ALICE_EMU32A+0xb, /* 32 */ - EMU_SRC_ALICE_EMU32A+0xc, /* 33 */ - EMU_SRC_ALICE_EMU32A+0xd, /* 34 */ - EMU_SRC_ALICE_EMU32A+0xe, /* 35 */ - EMU_SRC_ALICE_EMU32A+0xf, /* 36 */ - EMU_SRC_ALICE_EMU32B, /* 37 */ - EMU_SRC_ALICE_EMU32B+1, /* 38 */ - EMU_SRC_ALICE_EMU32B+2, /* 39 */ - EMU_SRC_ALICE_EMU32B+3, /* 40 */ - EMU_SRC_ALICE_EMU32B+4, /* 41 */ - EMU_SRC_ALICE_EMU32B+5, /* 42 */ - EMU_SRC_ALICE_EMU32B+6, /* 43 */ - EMU_SRC_ALICE_EMU32B+7, /* 44 */ - EMU_SRC_ALICE_EMU32B+8, /* 45 */ - EMU_SRC_ALICE_EMU32B+9, /* 46 */ - EMU_SRC_ALICE_EMU32B+0xa, /* 47 */ - EMU_SRC_ALICE_EMU32B+0xb, /* 48 */ - EMU_SRC_ALICE_EMU32B+0xc, /* 49 */ - EMU_SRC_ALICE_EMU32B+0xd, /* 50 */ - EMU_SRC_ALICE_EMU32B+0xe, /* 51 */ - EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ -}; - -static unsigned int emu1010_output_dst[] = { - EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ - EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ - EMU_DST_DOCK_DAC2_LEFT1, /* 2 */ - EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */ - EMU_DST_DOCK_DAC3_LEFT1, /* 4 */ - EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */ - EMU_DST_DOCK_DAC4_LEFT1, /* 6 */ - EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */ - EMU_DST_DOCK_PHONES_LEFT1, /* 8 */ - EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */ - EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */ - EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */ - EMU_DST_HANA_SPDIF_LEFT1, /* 12 */ - EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */ - EMU_DST_HAMOA_DAC_LEFT1, /* 14 */ - EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */ - EMU_DST_HANA_ADAT, /* 16 */ - EMU_DST_HANA_ADAT+1, /* 17 */ - EMU_DST_HANA_ADAT+2, /* 18 */ - EMU_DST_HANA_ADAT+3, /* 19 */ - EMU_DST_HANA_ADAT+4, /* 20 */ - EMU_DST_HANA_ADAT+5, /* 21 */ - EMU_DST_HANA_ADAT+6, /* 22 */ - EMU_DST_HANA_ADAT+7, /* 23 */ -}; - -static unsigned int emu1010_input_dst[] = { - EMU_DST_ALICE2_EMU32_0, - EMU_DST_ALICE2_EMU32_1, - EMU_DST_ALICE2_EMU32_2, - EMU_DST_ALICE2_EMU32_3, - EMU_DST_ALICE2_EMU32_4, - EMU_DST_ALICE2_EMU32_5, - EMU_DST_ALICE2_EMU32_6, - EMU_DST_ALICE2_EMU32_7, - EMU_DST_ALICE2_EMU32_8, - EMU_DST_ALICE2_EMU32_9, - EMU_DST_ALICE2_EMU32_A, - EMU_DST_ALICE2_EMU32_B, - EMU_DST_ALICE2_EMU32_C, - EMU_DST_ALICE2_EMU32_D, - EMU_DST_ALICE2_EMU32_E, - EMU_DST_ALICE2_EMU32_F, - EMU_DST_ALICE_I2S0_LEFT, - EMU_DST_ALICE_I2S0_RIGHT, - EMU_DST_ALICE_I2S1_LEFT, - EMU_DST_ALICE_I2S1_RIGHT, - EMU_DST_ALICE_I2S2_LEFT, - EMU_DST_ALICE_I2S2_RIGHT, -}; - -static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 53; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, emu1010_src_texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - int channel; - - channel = (kcontrol->private_value) & 0xff; - ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel]; - return 0; -} - -static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - int change = 0; - unsigned int val; - int channel; - - channel = (kcontrol->private_value) & 0xff; - if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) { - val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0]; - change = 1; - snd_emu1010_fpga_link_dst_src_write(emu, - emu1010_output_dst[channel], emu1010_src_regs[val]); - } - return change; -} - -static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - int channel; - - channel = (kcontrol->private_value) & 0xff; - ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel]; - return 0; -} - -static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - int change = 0; - unsigned int val; - int channel; - - channel = (kcontrol->private_value) & 0xff; - if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) { - val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0]; - change = 1; - snd_emu1010_fpga_link_dst_src_write(emu, - emu1010_input_dst[channel], emu1010_src_regs[val]); - } - return change; -} - -#define EMU1010_SOURCE_OUTPUT(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_emu1010_input_output_source_info, \ - .get = snd_emu1010_output_source_get, \ - .put = snd_emu1010_output_source_put, \ - .private_value = chid \ -} - -static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = { - EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0), - EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1), - EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2), - EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3), - EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4), - EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5), - EMU1010_SOURCE_OUTPUT("Dock DAC4 Left Playback Enum", 6), - EMU1010_SOURCE_OUTPUT("Dock DAC4 Right Playback Enum", 7), - EMU1010_SOURCE_OUTPUT("Dock Phones Left Playback Enum", 8), - EMU1010_SOURCE_OUTPUT("Dock Phones Right Playback Enum", 9), - EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 0xa), - EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 0xb), - EMU1010_SOURCE_OUTPUT("1010 SPDIF Left Playback Enum", 0xc), - EMU1010_SOURCE_OUTPUT("1010 SPDIF Right Playback Enum", 0xd), - EMU1010_SOURCE_OUTPUT("0202 DAC Left Playback Enum", 0xe), - EMU1010_SOURCE_OUTPUT("0202 DAC Right Playback Enum", 0xf), - EMU1010_SOURCE_OUTPUT("1010 ADAT 0 Playback Enum", 0x10), - EMU1010_SOURCE_OUTPUT("1010 ADAT 1 Playback Enum", 0x11), - EMU1010_SOURCE_OUTPUT("1010 ADAT 2 Playback Enum", 0x12), - EMU1010_SOURCE_OUTPUT("1010 ADAT 3 Playback Enum", 0x13), - EMU1010_SOURCE_OUTPUT("1010 ADAT 4 Playback Enum", 0x14), - EMU1010_SOURCE_OUTPUT("1010 ADAT 5 Playback Enum", 0x15), - EMU1010_SOURCE_OUTPUT("1010 ADAT 6 Playback Enum", 0x16), - EMU1010_SOURCE_OUTPUT("1010 ADAT 7 Playback Enum", 0x17), -}; - -#define EMU1010_SOURCE_INPUT(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_emu1010_input_output_source_info, \ - .get = snd_emu1010_input_source_get, \ - .put = snd_emu1010_input_source_put, \ - .private_value = chid \ -} - -static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = { - EMU1010_SOURCE_INPUT("DSP 0 Capture Enum", 0), - EMU1010_SOURCE_INPUT("DSP 1 Capture Enum", 1), - EMU1010_SOURCE_INPUT("DSP 2 Capture Enum", 2), - EMU1010_SOURCE_INPUT("DSP 3 Capture Enum", 3), - EMU1010_SOURCE_INPUT("DSP 4 Capture Enum", 4), - EMU1010_SOURCE_INPUT("DSP 5 Capture Enum", 5), - EMU1010_SOURCE_INPUT("DSP 6 Capture Enum", 6), - EMU1010_SOURCE_INPUT("DSP 7 Capture Enum", 7), - EMU1010_SOURCE_INPUT("DSP 8 Capture Enum", 8), - EMU1010_SOURCE_INPUT("DSP 9 Capture Enum", 9), - EMU1010_SOURCE_INPUT("DSP A Capture Enum", 0xa), - EMU1010_SOURCE_INPUT("DSP B Capture Enum", 0xb), - EMU1010_SOURCE_INPUT("DSP C Capture Enum", 0xc), - EMU1010_SOURCE_INPUT("DSP D Capture Enum", 0xd), - EMU1010_SOURCE_INPUT("DSP E Capture Enum", 0xe), - EMU1010_SOURCE_INPUT("DSP F Capture Enum", 0xf), - EMU1010_SOURCE_INPUT("DSP 10 Capture Enum", 0x10), - EMU1010_SOURCE_INPUT("DSP 11 Capture Enum", 0x11), - EMU1010_SOURCE_INPUT("DSP 12 Capture Enum", 0x12), - EMU1010_SOURCE_INPUT("DSP 13 Capture Enum", 0x13), - EMU1010_SOURCE_INPUT("DSP 14 Capture Enum", 0x14), - EMU1010_SOURCE_INPUT("DSP 15 Capture Enum", 0x15), -}; - - - - -static int snd_emu1010_adc_pads_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 snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int mask = kcontrol->private_value & 0xff; - ucontrol->value.integer.value[0] = (emu->emu1010.adc_pads & mask) ? 1 : 0; - return 0; -} - -static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int mask = kcontrol->private_value & 0xff; - unsigned int val, cache; - val = ucontrol->value.integer.value[0]; - cache = emu->emu1010.adc_pads; - if (val == 1) - cache = cache | mask; - else - cache = cache & ~mask; - if (cache != emu->emu1010.adc_pads) { - snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache ); - emu->emu1010.adc_pads = cache; - } - - return 0; -} - - - -#define EMU1010_ADC_PADS(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_emu1010_adc_pads_info, \ - .get = snd_emu1010_adc_pads_get, \ - .put = snd_emu1010_adc_pads_put, \ - .private_value = chid \ -} - -static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = { - EMU1010_ADC_PADS("ADC1 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD1), - EMU1010_ADC_PADS("ADC2 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD2), - EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3), - EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1), -}; - -static int snd_emu1010_dac_pads_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 snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int mask = kcontrol->private_value & 0xff; - ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0; - return 0; -} - -static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int mask = kcontrol->private_value & 0xff; - unsigned int val, cache; - val = ucontrol->value.integer.value[0]; - cache = emu->emu1010.dac_pads; - if (val == 1) - cache = cache | mask; - else - cache = cache & ~mask; - if (cache != emu->emu1010.dac_pads) { - snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache ); - emu->emu1010.dac_pads = cache; - } - - return 0; -} - - - -#define EMU1010_DAC_PADS(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ - .info = snd_emu1010_dac_pads_info, \ - .get = snd_emu1010_dac_pads_get, \ - .put = snd_emu1010_dac_pads_put, \ - .private_value = chid \ -} - -static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = { - EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1), - EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2), - EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3), - EMU1010_DAC_PADS("DAC4 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD4), - EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1), -}; - - -static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[2] = { - "44100", "48000" - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock; - return 0; -} - -static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int val; - int change = 0; - - val = ucontrol->value.enumerated.item[0] ; - change = (emu->emu1010.internal_clock != val); - if (change) { - emu->emu1010.internal_clock = val; - switch (val) { - case 0: - /* 44100 */ - /* Mute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); - /* Default fallback clock 48kHz */ - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K ); - /* Word Clock source, Internal 44.1kHz x1 */ - snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, - EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X ); - /* Set LEDs on Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, - EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK ); - /* Allow DLL to settle */ - msleep(10); - /* Unmute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); - break; - case 1: - /* 48000 */ - /* Mute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE ); - /* Default fallback clock 48kHz */ - snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K ); - /* Word Clock source, Internal 48kHz x1 */ - snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, - EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X ); - /* Set LEDs on Audio Dock */ - snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, - EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK ); - /* Allow DLL to settle */ - msleep(10); - /* Unmute all */ - snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); - break; - } - } - return change; -} - -static struct snd_kcontrol_new snd_emu1010_internal_clock = -{ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Clock Internal Rate", - .count = 1, - .info = snd_emu1010_internal_clock_info, - .get = snd_emu1010_internal_clock_get, - .put = snd_emu1010_internal_clock_put -}; - -static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ -#if 0 - static char *texts[4] = { - "Unknown1", "Unknown2", "Mic", "Line" - }; -#endif - static char *texts[2] = { - "Mic", "Line" - }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = emu->i2c_capture_source; - return 0; -} - -static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int source_id; - unsigned int ngain, ogain; - u32 gpio; - int change = 0; - unsigned long flags; - u32 source; - /* If the capture source has changed, - * update the capture volume from the cached value - * for the particular source. - */ - source_id = ucontrol->value.enumerated.item[0]; /* Use 2 and 3 */ - change = (emu->i2c_capture_source != source_id); - if (change) { - snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */ - spin_lock_irqsave(&emu->emu_lock, flags); - gpio = inl(emu->port + A_IOCFG); - if (source_id==0) - outl(gpio | 0x4, emu->port + A_IOCFG); - else - outl(gpio & ~0x4, emu->port + A_IOCFG); - spin_unlock_irqrestore(&emu->emu_lock, flags); - - ngain = emu->i2c_capture_volume[source_id][0]; /* Left */ - ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */ - if (ngain != ogain) - snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff)); - ngain = emu->i2c_capture_volume[source_id][1]; /* Right */ - ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */ - if (ngain != ogain) - snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); - - source = 1 << (source_id + 2); - snd_emu10k1_i2c_write(emu, ADC_MUX, source); /* Set source */ - emu->i2c_capture_source = source_id; - } - return change; -} - -static struct snd_kcontrol_new snd_audigy_i2c_capture_source = -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = snd_audigy_i2c_capture_source_info, - .get = snd_audigy_i2c_capture_source_get, - .put = snd_audigy_i2c_capture_source_put -}; - -static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 255; - return 0; -} - -static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - int source_id; - - source_id = kcontrol->private_value; - - ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0]; - ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1]; - return 0; -} - -static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); - unsigned int ogain; - unsigned int ngain; - int source_id; - int change = 0; - - source_id = kcontrol->private_value; - ogain = emu->i2c_capture_volume[source_id][0]; /* Left */ - ngain = ucontrol->value.integer.value[0]; - if (ngain > 0xff) - return 0; - if (ogain != ngain) { - if (emu->i2c_capture_source == source_id) - snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) ); - emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0]; - change = 1; - } - ogain = emu->i2c_capture_volume[source_id][1]; /* Right */ - ngain = ucontrol->value.integer.value[1]; - if (ngain > 0xff) - return 0; - if (ogain != ngain) { - if (emu->i2c_capture_source == source_id) - snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff)); - emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1]; - change = 1; - } - - return change; -} - -#define I2C_VOLUME(xname,chid) \ -{ \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ - SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ - .info = snd_audigy_i2c_volume_info, \ - .get = snd_audigy_i2c_volume_get, \ - .put = snd_audigy_i2c_volume_put, \ - .tlv = { .p = snd_audigy_db_scale2 }, \ - .private_value = chid \ -} - - -static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = { - I2C_VOLUME("Mic Capture Volume", 0), - I2C_VOLUME("Line Capture Volume", 0) -}; - #if 0 static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1340,9 +668,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, int change = 0; spin_lock_irqsave(&emu->reg_lock, flags); - if ( emu->card_capabilities->i2c_adc) { - /* Do nothing for Audigy 2 ZS Notebook */ - } else if (emu->audigy) { + if (emu->audigy) { reg = inl(emu->port + A_IOCFG); val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; change = (reg & A_IOCFG_GPOUT0) != val; @@ -1480,24 +806,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, "AMic Playback Volume", "Mic Playback Volume", NULL }; - static char *audigy_rename_ctls_i2c_adc[] = { - //"Analog Mix Capture Volume","OLD Analog Mix Capture Volume", - "Line Capture Volume", "Analog Mix Capture Volume", - "Wave Playback Volume", "OLD PCM Playback Volume", - "Wave Master Playback Volume", "Master Playback Volume", - "AMic Playback Volume", "Old Mic Playback Volume", - "CD Capture Volume", "IEC958 Optical Capture Volume", - NULL - }; - static char *audigy_remove_ctls_i2c_adc[] = { - /* On the Audigy2 ZS Notebook - * Capture via WM8775 */ - "Mic Capture Volume", - "Analog Mix Capture Volume", - "Aux Capture Volume", - "IEC958 Optical Capture Volume", - NULL - }; static char *audigy_remove_ctls_1361t_adc[] = { /* On the Audigy2 the AC97 playback is piped into * the Philips ADC for 24bit capture */ @@ -1582,7 +890,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, if (emu->ac97->id == AC97_ID_STAC9758) { emu->rear_ac97 = 1; snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); - snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); } /* remove unused AC97 controls */ snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); @@ -1591,10 +898,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, } for (; *c; c++) remove_ctl(card, *c); - } else if (emu->card_capabilities->i2c_adc) { - c = audigy_remove_ctls_i2c_adc; - for (; *c; c++) - remove_ctl(card, *c); } else { no_ac97: if (emu->card_capabilities->ecard) @@ -1608,8 +911,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, if (emu->audigy) if (emu->card_capabilities->adc_1361t) c = audigy_rename_ctls_1361t_adc; - else if (emu->card_capabilities->i2c_adc) - c = audigy_rename_ctls_i2c_adc; else c = audigy_rename_ctls; else @@ -1720,7 +1021,7 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, return err; } - if ( emu->card_capabilities->emu1010) { + if ( emu->card_capabilities->emu1212m) { ; /* Disable the snd_audigy_spdif_shared_spdif */ } else if (emu->audigy) { if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) @@ -1744,48 +1045,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, if ((err = snd_p16v_mixer(emu))) return err; } - - if ( emu->card_capabilities->emu1010) { - int i; - - for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_output_enum_ctls[i], emu)); - if (err < 0) - return err; - } - for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_input_enum_ctls[i], emu)); - if (err < 0) - return err; - } - for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_adc_pads[i], emu)); - if (err < 0) - return err; - } - for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_dac_pads[i], emu)); - if (err < 0) - return err; - } - err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_internal_clock, emu)); - if (err < 0) - return err; - } - - if ( emu->card_capabilities->i2c_adc) { - int i; - - err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_capture_source, emu)); - if (err < 0) - return err; - - for (i = 0; i < ARRAY_SIZE(snd_audigy_i2c_volume_ctls); i++) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_volume_ctls[i], emu)); - if (err < 0) - return err; - } - } return 0; } diff --git a/trunk/sound/pci/emu10k1/emupcm.c b/trunk/sound/pci/emu10k1/emupcm.c index ab4f5df5241b..717e92ec9e0a 100644 --- a/trunk/sound/pci/emu10k1/emupcm.c +++ b/trunk/sound/pci/emu10k1/emupcm.c @@ -147,7 +147,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic 1, &epcm->extra); if (err < 0) { - /* printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); */ + // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); for (i = 0; i < voices; i++) { snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); epcm->voices[i] = NULL; @@ -339,7 +339,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, } } - /* setup routing */ + // setup routing if (emu->audigy) { snd_emu10k1_ptr_write(emu, A_FXRT1, voice, snd_emu10k1_compose_audigy_fxrt1(send_routing)); @@ -353,15 +353,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, } else snd_emu10k1_ptr_write(emu, FXRT, voice, snd_emu10k1_compose_send_routing(send_routing)); - /* Stop CA */ - /* Assumption that PT is already 0 so no harm overwriting */ + // Stop CA + // Assumption that PT is already 0 so no harm overwriting snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); - if (emu->card_capabilities->emu1010) - pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ - else - pitch_target = emu10k1_calc_pitch_target(runtime->rate); + pitch_target = emu10k1_calc_pitch_target(runtime->rate); if (extra) snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr | emu10k1_select_interprom(pitch_target) | @@ -370,14 +367,14 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) | emu10k1_select_interprom(pitch_target) | (w_16 ? 0 : CCCA_8BITSELECT)); - /* Clear filter delay memory */ + // Clear filter delay memory snd_emu10k1_ptr_write(emu, Z1, voice, 0); snd_emu10k1_ptr_write(emu, Z2, voice, 0); - /* invalidate maps */ + // invalidate maps silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); - /* modulation envelope */ + // modulation envelope snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0); @@ -388,12 +385,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0); snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0); snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000); - /* volume envelope */ + // volume envelope snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f); snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000); - /* filter envelope */ + // filter envelope snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f); - /* pitch envelope */ + // pitch envelope snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0); spin_unlock_irqrestore(&emu->reg_lock, flags); @@ -471,7 +468,7 @@ static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream) snd_emu10k1_voice_free(epcm->emu, epcm->extra); epcm->extra = NULL; } - for (i = 0; i < NUM_EFX_PLAYBACK; i++) { + for (i=0; i < NUM_EFX_PLAYBACK; i++) { if (epcm->voices[i]) { snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); epcm->voices[i] = NULL; @@ -640,7 +637,7 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e stereo = (!extra && runtime->channels == 2); sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; ccis = emu10k1_ccis(stereo, sample == 0); - /* set cs to 2 * number of cache registers beside the invalidated */ + // set cs to 2 * number of cache registers beside the invalidated cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1; if (cs > 16) cs = 16; for (i = 0; i < cs; i++) { @@ -649,14 +646,14 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample); } } - /* reset cache */ + // reset cache snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0); snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra); if (stereo) { snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0); snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra); } - /* fill cache */ + // fill cache snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis); if (stereo) { snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis); @@ -701,10 +698,7 @@ static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct s voice = evoice->number; pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8; - if (emu->card_capabilities->emu1010) - pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */ - else - pitch_target = emu10k1_calc_pitch_target(runtime->rate); + pitch_target = emu10k1_calc_pitch_target(runtime->rate); snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target); if (master || evoice->epcm->type == PLAYBACK_EFX) snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target); @@ -738,7 +732,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, struct snd_emu10k1_pcm_mixer *mix; int result = 0; - /* printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); */ + // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); spin_lock(&emu->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -784,10 +778,10 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - /* hmm this should cause full and half full interrupt to be raised? */ + // hmm this should cause full and half full interrupt to be raised? outl(epcm->capture_ipr, emu->port + IPR); snd_emu10k1_intr_enable(emu, epcm->capture_inte); - /* printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); */ + // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); switch (epcm->type) { case CAPTURE_AC97ADC: snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val); @@ -796,7 +790,6 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream, if (emu->audigy) { snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val); snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2); - snd_printdd("cr_val=0x%x, cr_val2=0x%x\n", epcm->capture_cr_val, epcm->capture_cr_val2); } else snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); break; @@ -858,7 +851,7 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream * ptr -= runtime->buffer_size; } #endif - /* printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); */ + // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); return ptr; } @@ -875,7 +868,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream, spin_lock(&emu->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* prepare voices */ + // prepare voices for (i = 0; i < NUM_EFX_PLAYBACK; i++) { snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); } @@ -924,7 +917,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s if (!epcm->running) return 0; if (epcm->first_ptr) { - udelay(50); /* hack, it takes awhile until capture is started */ + udelay(50); // hack, it takes awhile until capture is started epcm->first_ptr = 0; } ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff; @@ -979,28 +972,6 @@ static struct snd_pcm_hardware snd_emu10k1_capture = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_emu10k1_capture_efx = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .rate_min = 44100, - .rate_max = 192000, - .channels_min = 8, - .channels_max = 8, - .buffer_bytes_max = (64*1024), - .period_bytes_min = 384, - .period_bytes_max = (64*1024), - .periods_min = 2, - .periods_max = 2, - .fifo_size = 0, -}; - /* * */ @@ -1045,7 +1016,7 @@ static int snd_emu10k1_efx_playback_close(struct snd_pcm_substream *substream) struct snd_emu10k1_pcm_mixer *mix; int i; - for (i = 0; i < NUM_EFX_PLAYBACK; i++) { + for (i=0; i < NUM_EFX_PLAYBACK; i++) { mix = &emu->efx_pcm_mixer[i]; mix->epcm = NULL; snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0); @@ -1074,7 +1045,7 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream) runtime->private_free = snd_emu10k1_pcm_free_substream; runtime->hw = snd_emu10k1_efx_playback; - for (i = 0; i < NUM_EFX_PLAYBACK; i++) { + for (i=0; i < NUM_EFX_PLAYBACK; i++) { mix = &emu->efx_pcm_mixer[i]; mix->send_routing[0][0] = i; memset(&mix->send_volume, 0, sizeof(mix->send_volume)); @@ -1228,69 +1199,15 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) epcm->capture_idx_reg = FXIDX; substream->runtime->private_data = epcm; substream->runtime->private_free = snd_emu10k1_pcm_free_substream; - runtime->hw = snd_emu10k1_capture_efx; + runtime->hw = snd_emu10k1_capture; runtime->hw.rates = SNDRV_PCM_RATE_48000; runtime->hw.rate_min = runtime->hw.rate_max = 48000; spin_lock_irq(&emu->reg_lock); - if (emu->card_capabilities->emu1010) { - /* TODO - * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE - * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 - * rate_min = 44100, - * rate_max = 192000, - * channels_min = 8, - * channels_max = 8, - * Need to add mixer control to fix sample rate - * - * There are 16 mono channels of 16bits each. - * 24bit Audio uses 2x channels over 16bit - * 96kHz uses 2x channels over 48kHz - * 192kHz uses 4x channels over 48kHz - * So, for 48kHz 24bit, one has 8 channels - * for 96kHz 24bit, one has 4 channels - * for 192kHz 24bit, one has 2 channels - */ -#if 1 - switch (emu->emu1010.internal_clock) { - case 0: - /* For 44.1kHz */ - runtime->hw.rates = SNDRV_PCM_RATE_44100; - runtime->hw.rate_min = runtime->hw.rate_max = 44100; - runtime->hw.channels_min = runtime->hw.channels_max = 8; - break; - case 1: - /* For 48kHz */ - runtime->hw.rates = SNDRV_PCM_RATE_48000; - runtime->hw.rate_min = runtime->hw.rate_max = 48000; - runtime->hw.channels_min = runtime->hw.channels_max = 8; - break; - }; -#endif -#if 0 - /* For 96kHz */ - runtime->hw.rates = SNDRV_PCM_RATE_96000; - runtime->hw.rate_min = runtime->hw.rate_max = 96000; - runtime->hw.channels_min = runtime->hw.channels_max = 4; -#endif -#if 0 - /* For 192kHz */ - runtime->hw.rates = SNDRV_PCM_RATE_192000; - runtime->hw.rate_min = runtime->hw.rate_max = 192000; - runtime->hw.channels_min = runtime->hw.channels_max = 2; -#endif - runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; - /* efx_voices_mask[0] is expected to be zero - * efx_voices_mask[1] is expected to have 16bits set - */ - } else { - runtime->hw.channels_min = runtime->hw.channels_max = 0; - for (idx = 0; idx < nefx; idx++) { - if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { - runtime->hw.channels_min++; - runtime->hw.channels_max++; - } + runtime->hw.channels_min = runtime->hw.channels_max = 0; + for (idx = 0; idx < nefx; idx++) { + if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { + runtime->hw.channels_min++; + runtime->hw.channels_max++; } } epcm->capture_cr_val = emu->efx_voices_mask[0]; @@ -1543,7 +1460,7 @@ static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left, unsigned int count, unsigned int tram_shift) { - /* printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); */ + // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); if ((tram_shift & 1) == 0) { while (count--) { *dst_left-- = *src++; @@ -1620,7 +1537,7 @@ static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substre struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; unsigned int i; - /* printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); */ + // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec)); pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */ pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); diff --git a/trunk/sound/pci/emu10k1/emuproc.c b/trunk/sound/pci/emu10k1/emuproc.c index 2c1585991bc8..b939e03aaedf 100644 --- a/trunk/sound/pci/emu10k1/emuproc.c +++ b/trunk/sound/pci/emu10k1/emuproc.c @@ -3,9 +3,6 @@ * Creative Labs, Inc. * Routines for control of EMU10K1 chips / proc interface routines * - * Copyright (c) by James Courtier-Dutton - * Added EMU 1010 support. - * * BUGS: * -- * @@ -258,7 +255,7 @@ static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry, unsigned int val, tmp, n; val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); tmp = (val >> 16) & 0x8; - for (n = 0; n < 4; n++) { + for (n=0;n<4;n++) { tmp = val >> (16 + (n*4)); if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); else snd_iprintf(buffer, "Channel %d: No input\n", n); @@ -375,27 +372,6 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, } #ifdef CONFIG_SND_DEBUG -static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) -{ - struct snd_emu10k1 *emu = entry->private_data; - unsigned long value; - unsigned long flags; - unsigned long regs; - int i; - snd_iprintf(buffer, "EMU1010 Registers:\n\n"); - - for(i = 0; i < 0x30; i+=1) { - spin_lock_irqsave(&emu->emu_lock, flags); - regs=i+0x40; /* 0x40 upwards are registers. */ - outl(regs, emu->port + A_IOCFG); - outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - value = inl(emu->port + A_IOCFG); - spin_unlock_irqrestore(&emu->emu_lock, flags); - snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f); - } -} - static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { @@ -422,7 +398,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry, while (!snd_info_get_line(buffer, line, sizeof(line))) { if (sscanf(line, "%x %x", ®, &val) != 2) continue; - if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) { + if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) { spin_lock_irqsave(&emu->emu_lock, flags); outl(val, emu->port + (reg & 0xfffffffc)); spin_unlock_irqrestore(&emu->emu_lock, flags); @@ -498,7 +474,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry, while (!snd_info_get_line(buffer, line, sizeof(line))) { if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) continue; - if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) ) + if ((reg < 0xa0) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) ) snd_ptr_write(emu, iobase, reg, channel_id, val); } } @@ -555,10 +531,6 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu) { struct snd_info_entry *entry; #ifdef CONFIG_SND_DEBUG - if ((emu->card_capabilities->emu1010) && - snd_card_proc_new(emu->card, "emu1010_regs", &entry)) { - snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read); - } if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); entry->c.text.write = snd_emu_proc_io_reg_write; diff --git a/trunk/sound/pci/emu10k1/io.c b/trunk/sound/pci/emu10k1/io.c index 116e1c8d9361..029e7856c43b 100644 --- a/trunk/sound/pci/emu10k1/io.c +++ b/trunk/sound/pci/emu10k1/io.c @@ -30,7 +30,6 @@ #include #include #include -#include "p17v.h" unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) { @@ -168,109 +167,6 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, return 0; } -/* The ADC does not support i2c read, so only write is implemented */ -int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, - u32 reg, - u32 value) -{ - u32 tmp; - int timeout = 0; - int status; - int retry; - if ((reg > 0x7f) || (value > 0x1ff)) { - snd_printk(KERN_ERR "i2c_write: invalid values.\n"); - return -EINVAL; - } - - tmp = reg << 25 | value << 16; - // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value); - /* Not sure what this I2C channel controls. */ - /* snd_emu10k1_ptr_write(emu, P17V_I2C_0, 0, tmp); */ - - /* This controls the I2C connected to the WM8775 ADC Codec */ - snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp); - tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */ - - for (retry = 0; retry < 10; retry++) { - /* Send the data to i2c */ - //tmp = snd_emu10k1_ptr_read(emu, P17V_I2C_ADDR, 0); - //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK); - tmp = 0; - tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD); - snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp); - - /* Wait till the transaction ends */ - while (1) { - udelay(10); - status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0); - // snd_printk("I2C:status=0x%x\n", status); - timeout++; - if ((status & I2C_A_ADC_START) == 0) - break; - - if (timeout > 1000) { - snd_printk("emu10k1:I2C:timeout status=0x%x\n", status); - break; - } - } - //Read back and see if the transaction is successful - if ((status & I2C_A_ADC_ABORT) == 0) - break; - } - - if (retry == 10) { - snd_printk(KERN_ERR "Writing to ADC failed!\n"); - return -EINVAL; - } - - return 0; -} - -int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value) -{ - if (reg < 0 || reg > 0x3f) - return 1; - reg += 0x40; /* 0x40 upwards are registers. */ - if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */ - return 1; - outl(reg, emu->port + A_IOCFG); - udelay(10); - outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - udelay(10); - outl(value, emu->port + A_IOCFG); - udelay(10); - outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - - return 0; -} - -int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) -{ - if (reg < 0 || reg > 0x3f) - return 1; - reg += 0x40; /* 0x40 upwards are registers. */ - outl(reg, emu->port + A_IOCFG); - udelay(10); - outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ - udelay(10); - *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f); - - return 0; -} - -/* Each Destination has one and only one Source, - * but one Source can feed any number of Destinations simultaneously. - */ -int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src) -{ - snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) ); - snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) ); - - return 0; -} - void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) { unsigned long flags; diff --git a/trunk/sound/pci/emu10k1/p16v.c b/trunk/sound/pci/emu10k1/p16v.c index 465f8d505329..4e0f95438f47 100644 --- a/trunk/sound/pci/emu10k1/p16v.c +++ b/trunk/sound/pci/emu10k1/p16v.c @@ -253,7 +253,7 @@ static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream) struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); //struct snd_pcm_runtime *runtime = substream->runtime; //struct snd_emu10k1_pcm *epcm = runtime->private_data; - emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0; + emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; /* FIXME: maybe zero others */ return 0; } @@ -264,7 +264,7 @@ static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream) struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); //struct snd_pcm_runtime *runtime = substream->runtime; //struct snd_emu10k1_pcm *epcm = runtime->private_data; - emu->p16v_capture_voice.use = 0; + emu->p16v_capture_voice.use=0; /* FIXME: maybe zero others */ return 0; } @@ -349,7 +349,7 @@ static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream) break; } /* FIXME: Check emu->buffer.size before actually writing to it. */ - for(i = 0; i < runtime->periods; i++) { + for(i=0; i < runtime->periods; i++) { table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); table_base[(i*2)+1]=period_size_bytes<<16; } @@ -394,7 +394,7 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream) /* FIXME: Check emu->buffer.size before actually writing to it. */ snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); - snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes + snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<voices[(first_voice + i) % NUM_G]; // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number); voice->use = 1; diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 425b167522d5..a84f6b21024f 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -413,6 +413,8 @@ struct ensoniq { } u; struct pci_dev *pci; + unsigned short subsystem_vendor_id; + unsigned short subsystem_device_id; struct snd_card *card; struct snd_pcm *pcm1; /* DAC1/ADC PCM */ struct snd_pcm *pcm2; /* DAC2 PCM */ @@ -1605,26 +1607,11 @@ static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97) ensoniq->u.es1371.ac97 = NULL; } -struct es1371_quirk { +static struct { unsigned short vid; /* vendor ID */ unsigned short did; /* device ID */ unsigned char rev; /* revision */ -}; - -static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq, - struct es1371_quirk *list) -{ - while (list->vid != (unsigned short)PCI_ANY_ID) { - if (ensoniq->pci->vendor == list->vid && - ensoniq->pci->device == list->did && - ensoniq->rev == list->rev) - return 1; - list++; - } - return 0; -} - -static struct es1371_quirk es1371_spdif_present[] __devinitdata = { +} es1371_spdif_present[] __devinitdata = { { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, @@ -1633,19 +1620,12 @@ static struct es1371_quirk es1371_spdif_present[] __devinitdata = { { .vid = PCI_ANY_ID, .did = PCI_ANY_ID } }; -static struct snd_pci_quirk ens1373_line_quirk[] __devinitdata = { - SND_PCI_QUIRK_ID(0x1274, 0x2000), /* GA-7DXR */ - SND_PCI_QUIRK_ID(0x1458, 0xa000), /* GA-8IEXP */ - { } /* end */ -}; - -static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, - int has_spdif, int has_line) +static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int has_line) { struct snd_card *card = ensoniq->card; struct snd_ac97_bus *pbus; struct snd_ac97_template ac97; - int err; + int err, idx; static struct snd_ac97_bus_ops ops = { .write = snd_es1371_codec_write, .read = snd_es1371_codec_read, @@ -1661,28 +1641,33 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, ac97.scaps = AC97_SCAP_AUDIO; if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0) return err; - if (has_spdif > 0 || - (!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) { - struct snd_kcontrol *kctl; - int i, index = 0; - - ensoniq->spdif_default = ensoniq->spdif_stream = - SNDRV_PCM_DEFAULT_CON_SPDIF; - outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS)); - - if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF) - index++; - - for (i = 0; i < ARRAY_SIZE(snd_es1371_mixer_spdif); i++) { - kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq); - if (!kctl) - return -ENOMEM; - kctl->id.index = index; - err = snd_ctl_add(card, kctl); - if (err < 0) - return err; + for (idx = 0; es1371_spdif_present[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if ((ensoniq->pci->vendor == es1371_spdif_present[idx].vid && + ensoniq->pci->device == es1371_spdif_present[idx].did && + ensoniq->rev == es1371_spdif_present[idx].rev) || has_spdif > 0) { + struct snd_kcontrol *kctl; + int i, index = 0; + + if (has_spdif < 0) + break; + + ensoniq->spdif_default = ensoniq->spdif_stream = + SNDRV_PCM_DEFAULT_CON_SPDIF; + outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS)); + + if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF) + index++; + + for (i = 0; i < (int)ARRAY_SIZE(snd_es1371_mixer_spdif); i++) { + kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq); + if (! kctl) + return -ENOMEM; + kctl->id.index = index; + if ((err = snd_ctl_add(card, kctl)) < 0) + return err; + } + break; } - } if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) { /* mirror rear to front speakers */ ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24); @@ -1691,10 +1676,12 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq, if (err < 0) return err; } - if (has_line > 0 || - snd_pci_quirk_lookup(ensoniq->pci, ens1373_line_quirk)) { - err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, - ensoniq)); + if (((ensoniq->subsystem_vendor_id == 0x1274) && + (ensoniq->subsystem_device_id == 0x2000)) || /* GA-7DXR */ + ((ensoniq->subsystem_vendor_id == 0x1458) && + (ensoniq->subsystem_device_id == 0xa000)) || /* GA-8IEXP */ + has_line > 0) { + err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, ensoniq)); if (err < 0) return err; } @@ -1969,15 +1956,21 @@ static int snd_ensoniq_dev_free(struct snd_device *device) } #ifdef CHIP1371 -static struct snd_pci_quirk es1371_amplifier_hack[] __devinitdata = { - SND_PCI_QUIRK_ID(0x107b, 0x2150), /* Gateway Solo 2150 */ - SND_PCI_QUIRK_ID(0x13bd, 0x100c), /* EV1938 on Mebius PC-MJ100V */ - SND_PCI_QUIRK_ID(0x1102, 0x5938), /* Targa Xtender300 */ - SND_PCI_QUIRK_ID(0x1102, 0x8938), /* IPC Topnote G notebook */ - { } /* end */ +static struct { + unsigned short svid; /* subsystem vendor ID */ + unsigned short sdid; /* subsystem device ID */ +} es1371_amplifier_hack[] = { + { .svid = 0x107b, .sdid = 0x2150 }, /* Gateway Solo 2150 */ + { .svid = 0x13bd, .sdid = 0x100c }, /* EV1938 on Mebius PC-MJ100V */ + { .svid = 0x1102, .sdid = 0x5938 }, /* Targa Xtender300 */ + { .svid = 0x1102, .sdid = 0x8938 }, /* IPC Topnote G notebook */ + { .svid = PCI_ANY_ID, .sdid = PCI_ANY_ID } }; - -static struct es1371_quirk es1371_ac97_reset_hack[] = { +static struct { + unsigned short vid; /* vendor ID */ + unsigned short did; /* device ID */ + unsigned char rev; /* revision */ +} es1371_ac97_reset_hack[] = { { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, @@ -1991,6 +1984,7 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq) { #ifdef CHIP1371 int idx; + struct pci_dev *pci = ensoniq->pci; #endif /* this code was part of snd_ensoniq_create before intruduction * of suspend/resume @@ -2005,12 +1999,16 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq) outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); outl(0, ES_REG(ensoniq, 1371_LEGACY)); - if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack)) { - outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); - /* need to delay around 20ms(bleech) to give - some CODECs enough time to wakeup */ - msleep(20); - } + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + msleep(20); + break; + } /* AC'97 warm reset to start the bitclk */ outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); inl(ES_REG(ensoniq, CONTROL)); @@ -2114,7 +2112,11 @@ static int __devinit snd_ensoniq_create(struct snd_card *card, struct ensoniq ** rensoniq) { struct ensoniq *ensoniq; + unsigned short cmdw; unsigned char cmdb; +#ifdef CHIP1371 + int idx; +#endif int err; static struct snd_device_ops ops = { .dev_free = snd_ensoniq_dev_free, @@ -2157,6 +2159,10 @@ static int __devinit snd_ensoniq_create(struct snd_card *card, pci_set_master(pci); pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb); ensoniq->rev = cmdb; + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw); + ensoniq->subsystem_vendor_id = cmdw; + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw); + ensoniq->subsystem_device_id = cmdw; #ifdef CHIP1370 #if 0 ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | @@ -2169,11 +2175,19 @@ static int __devinit snd_ensoniq_create(struct snd_card *card, ensoniq->ctrl = 0; ensoniq->sctrl = 0; ensoniq->cssr = 0; - if (snd_pci_quirk_lookup(pci, es1371_amplifier_hack)) - ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ - - if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack)) - ensoniq->cssr |= ES_1371_ST_AC97_RST; + for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++) + if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid && + ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) { + ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ + break; + } + for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) + if (pci->vendor == es1371_ac97_reset_hack[idx].vid && + pci->device == es1371_ac97_reset_hack[idx].did && + ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { + ensoniq->cssr |= ES_1371_ST_AC97_RST; + break; + } #endif snd_ensoniq_chip_init(ensoniq); diff --git a/trunk/sound/pci/es1938.c b/trunk/sound/pci/es1938.c index fec29a108945..66ac26c5a240 100644 --- a/trunk/sound/pci/es1938.c +++ b/trunk/sound/pci/es1938.c @@ -1344,7 +1344,7 @@ static unsigned int db_scale_line[] = { 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), }; -static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); static struct snd_kcontrol_new snd_es1938_controls[] = { ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0, diff --git a/trunk/sound/pci/fm801.c b/trunk/sound/pci/fm801.c index 6dc578bbeec9..b7b361ce3a93 100644 --- a/trunk/sound/pci/fm801.c +++ b/trunk/sound/pci/fm801.c @@ -1157,7 +1157,7 @@ static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol, return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val); } -static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0); #define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls) diff --git a/trunk/sound/pci/hda/Makefile b/trunk/sound/pci/hda/Makefile index 60d7b05a204a..dbacba6177db 100644 --- a/trunk/sound/pci/hda/Makefile +++ b/trunk/sound/pci/hda/Makefile @@ -1,14 +1,5 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o \ - hda_generic.o \ - patch_realtek.o \ - patch_cmedia.o \ - patch_analog.o \ - patch_sigmatel.o \ - patch_si3054.o \ - patch_atihdmi.o \ - patch_conexant.o \ - patch_via.o +snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o ifdef CONFIG_PROC_FS snd-hda-codec-objs += hda_proc.o endif diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 8f34fb447983..18bbc87e376f 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -52,7 +52,6 @@ struct hda_vendor_id { static struct hda_vendor_id hda_vendor_ids[] = { { 0x10ec, "Realtek" }, { 0x1057, "Motorola" }, - { 0x1106, "VIA" }, { 0x11d4, "Analog Devices" }, { 0x13f6, "C-Media" }, { 0x14f1, "Conexant" }, @@ -263,7 +262,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) unsol->queue[wp] = res; unsol->queue[wp + 1] = res_ex; - schedule_work(&unsol->work); + queue_work(unsol->workq, &unsol->work); return 0; } @@ -310,6 +309,12 @@ static int init_unsol_queue(struct hda_bus *bus) snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); return -ENOMEM; } + unsol->workq = create_singlethread_workqueue("hda_codec"); + if (! unsol->workq) { + snd_printk(KERN_ERR "hda_codec: can't create workqueue\n"); + kfree(unsol); + return -ENOMEM; + } INIT_WORK(&unsol->work, process_unsol_events); unsol->bus = bus; bus->unsol = unsol; @@ -328,7 +333,7 @@ static int snd_hda_bus_free(struct hda_bus *bus) if (! bus) return 0; if (bus->unsol) { - flush_scheduled_work(); + destroy_workqueue(bus->unsol->workq); kfree(bus->unsol); } list_for_each_safe(p, n, &bus->codec_list) { @@ -1709,8 +1714,6 @@ EXPORT_SYMBOL(snd_hda_build_pcms); /** * snd_hda_check_board_config - compare the current codec with the config table * @codec: the HDA codec - * @num_configs: number of config enums - * @models: array of model name strings * @tbl: configuration table, terminated by null entries * * Compares the modelname or PCI subsystem id of the current codec with the @@ -1719,44 +1722,33 @@ 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) -{ - if (codec->bus->modelname && models) { - int i; - for (i = 0; i < num_configs; i++) { - if (models[i] && - !strcmp(codec->bus->modelname, models[i])) { - snd_printd(KERN_INFO "hda_codec: model '%s' is " - "selected\n", models[i]); - return i; +int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) +{ + const struct hda_board_config *c; + + if (codec->bus->modelname) { + for (c = tbl; c->modelname || c->pci_subvendor; c++) { + if (c->modelname && + ! strcmp(codec->bus->modelname, c->modelname)) { + snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname); + return c->config; } } } - if (!codec->bus->pci || !tbl) - return -1; - - tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl); - if (!tbl) - return -1; - if (tbl->value >= 0 && tbl->value < num_configs) { -#ifdef CONFIG_SND_DEBUG_DETECT - char tmp[10]; - const char *model = NULL; - if (models) - model = models[tbl->value]; - if (!model) { - sprintf(tmp, "#%d", tbl->value); - model = tmp; + if (codec->bus->pci) { + u16 subsystem_vendor, subsystem_device; + pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); + pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device); + for (c = tbl; c->modelname || c->pci_subvendor; c++) { + if (c->pci_subvendor == subsystem_vendor && + (! c->pci_subdevice /* all match */|| + (c->pci_subdevice == subsystem_device))) { + snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", + subsystem_vendor, subsystem_device, c->config); + return c->config; + } } - snd_printdd(KERN_INFO "hda_codec: model '%s' is selected " - "for config %x:%x (%s)\n", - model, tbl->subvendor, tbl->subdevice, - (tbl->name ? tbl->name : "Unknown device")); -#endif - return tbl->value; } return -1; } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index b9a8e238b0a8..1a7e82104bb9 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -199,7 +199,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* STATESTS int mask: SD2,SD1,SD0 */ #define STATESTS_INT_MASK 0x07 -#define AZX_MAX_CODECS 3 +#define AZX_MAX_CODECS 4 /* SD_CTL bits */ #define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ @@ -1285,7 +1285,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - 1024 * 64, 1024 * 1024); + 1024 * 64, 1024 * 128); chip->pcm[pcm_dev] = pcm; if (chip->pcm_devs < pcm_dev + 1) chip->pcm_devs = pcm_dev + 1; @@ -1391,7 +1391,6 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect) return -1; } chip->irq = chip->pci->irq; - pci_intx(chip->pci, !chip->msi); return 0; } @@ -1502,31 +1501,6 @@ static int azx_dev_free(struct snd_device *device) return azx_free(device->device_data); } -/* - * white/black-listing for position_fix - */ -static const struct snd_pci_quirk position_fix_list[] __devinitdata = { - SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), - {} -}; - -static int __devinit check_position_fix(struct azx *chip, int fix) -{ - const struct snd_pci_quirk *q; - - if (fix == POS_FIX_AUTO) { - q = snd_pci_quirk_lookup(chip->pci, position_fix_list); - if (q) { - snd_printdd(KERN_INFO - "hda_intel: position_fix set to %d " - "for device %04x:%04x\n", - q->value, q->subvendor, q->subdevice); - return q->value; - } - } - return fix; -} - /* * constructor */ @@ -1561,8 +1535,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->driver_type = driver_type; chip->msi = enable_msi; - chip->position_fix = check_position_fix(chip, position_fix); - + chip->position_fix = position_fix; chip->single_cmd = single_cmd; #if BITS_PER_LONG != 64 diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 39718d6cdadd..9ca1baf860bd 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -173,9 +173,14 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } /* * Misc */ -int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, - const char **modelnames, - const struct snd_pci_quirk *pci_list); +struct hda_board_config { + const char *modelname; + int config; + unsigned short pci_subvendor; + unsigned short pci_subdevice; +}; + +int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); /* @@ -199,6 +204,7 @@ struct hda_bus_unsolicited { unsigned int rp, wp; /* workqueue */ + struct workqueue_struct *workq; struct work_struct work; struct hda_bus *bus; }; diff --git a/trunk/sound/pci/hda/hda_patch.h b/trunk/sound/pci/hda/hda_patch.h index 9f9e9ae44a9d..0b668793face 100644 --- a/trunk/sound/pci/hda/hda_patch.h +++ b/trunk/sound/pci/hda/hda_patch.h @@ -14,10 +14,6 @@ extern struct hda_codec_preset snd_hda_preset_sigmatel[]; extern struct hda_codec_preset snd_hda_preset_si3054[]; /* ATI HDMI codecs */ extern struct hda_codec_preset snd_hda_preset_atihdmi[]; -/* Conexant audio codec */ -extern struct hda_codec_preset snd_hda_preset_conexant[]; -/* VIA codecs */ -extern struct hda_codec_preset snd_hda_preset_via[]; static const struct hda_codec_preset *hda_preset_tables[] = { snd_hda_preset_realtek, @@ -26,7 +22,5 @@ static const struct hda_codec_preset *hda_preset_tables[] = { snd_hda_preset_sigmatel, snd_hda_preset_si3054, snd_hda_preset_atihdmi, - snd_hda_preset_conexant, - snd_hda_preset_via, NULL }; diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 38977bce70e2..076365bc10e9 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -782,63 +782,54 @@ static struct hda_channel_mode ad1986a_modes[3] = { /* eapd initialization */ static struct hda_verb ad1986a_eapd_init_verbs[] = { - {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, + {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, {} }; -/* Ultra initialization */ -static struct hda_verb ad1986a_ultra_init[] = { - /* eapd initialization */ - { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, - /* CLFE -> Mic in */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 }, - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, - { } /* end */ -}; - /* models */ -enum { - AD1986A_6STACK, - AD1986A_3STACK, - AD1986A_LAPTOP, - AD1986A_LAPTOP_EAPD, - AD1986A_ULTRA, - AD1986A_MODELS -}; - -static const char *ad1986a_models[AD1986A_MODELS] = { - [AD1986A_6STACK] = "6stack", - [AD1986A_3STACK] = "3stack", - [AD1986A_LAPTOP] = "laptop", - [AD1986A_LAPTOP_EAPD] = "laptop-eapd", - [AD1986A_ULTRA] = "ultra", -}; - -static struct snd_pci_quirk ad1986a_cfg_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), - SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD), - 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, 0x817f, "ASUS P5", AD1986A_3STACK), - SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), - SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), - SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), - SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), - SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), - SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), - SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), - SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), - SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), +enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD }; + +static struct hda_board_config ad1986a_cfg_tbl[] = { + { .modelname = "6stack", .config = AD1986A_6STACK }, + { .modelname = "3stack", .config = AD1986A_3STACK }, + { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, + .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x817f, + .config = AD1986A_3STACK }, /* ASUS P5P-L2 */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3, + .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x81cb, + .config = AD1986A_3STACK }, /* ASUS M2NPV-VM */ + { .modelname = "laptop", .config = AD1986A_LAPTOP }, + { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, + .config = AD1986A_LAPTOP }, /* FSC V2060 */ + { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, + .config = AD1986A_LAPTOP }, /* Samsung M50 */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, + .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ + { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, + { .pci_subvendor = 0x144d, .pci_subdevice = 0xc023, + .config = AD1986A_LAPTOP_EAPD }, /* Samsung X60 Chane */ + { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, + .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ + { .pci_subvendor = 0x144d, .pci_subdevice = 0xc026, + .config = AD1986A_LAPTOP_EAPD }, /* Samsung X11-T2300 Culesa */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1263, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x12b3, + .config = AD1986A_LAPTOP_EAPD }, /* ASUS V1j */ + { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, + .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ + { .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066, + .config = AD1986A_LAPTOP_EAPD }, /* Lenovo 3000 N100-07684JU */ {} }; @@ -870,9 +861,7 @@ static int patch_ad1986a(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; /* override some parameters */ - board_config = snd_hda_check_board_config(codec, AD1986A_MODELS, - ad1986a_models, - ad1986a_cfg_tbl); + board_config = snd_hda_check_board_config(codec, ad1986a_cfg_tbl); switch (board_config) { case AD1986A_3STACK: spec->num_mixers = 2; @@ -902,15 +891,6 @@ static int patch_ad1986a(struct hda_codec *codec) spec->multiout.dig_out_nid = 0; spec->input_mux = &ad1986a_laptop_eapd_capture_source; break; - case AD1986A_ULTRA: - spec->mixers[0] = ad1986a_laptop_eapd_mixers; - spec->num_init_verbs = 2; - spec->init_verbs[1] = ad1986a_ultra_init; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; - spec->multiout.dig_out_nid = 0; - break; } return 0; @@ -1411,27 +1391,20 @@ static struct hda_input_mux ad1981_thinkpad_capture_source = { }; /* models */ -enum { - AD1981_BASIC, - AD1981_HP, - AD1981_THINKPAD, - AD1981_MODELS -}; - -static const char *ad1981_models[AD1981_MODELS] = { - [AD1981_HP] = "hp", - [AD1981_THINKPAD] = "thinkpad", - [AD1981_BASIC] = "basic", -}; +enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD }; -static struct snd_pci_quirk ad1981_cfg_tbl[] = { +static struct hda_board_config ad1981_cfg_tbl[] = { + { .modelname = "hp", .config = AD1981_HP }, /* All HP models */ - SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP), - /* HP nx6320 (reversed SSID, H/W bug) */ - SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), + { .pci_subvendor = 0x103c, .config = AD1981_HP }, + { .pci_subvendor = 0x30b0, .pci_subdevice = 0x103c, + .config = AD1981_HP }, /* HP nx6320 (reversed SSID, H/W bug) */ + { .modelname = "thinkpad", .config = AD1981_THINKPAD }, /* Lenovo Thinkpad T60/X60/Z6xx */ - SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD), - SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), + { .pci_subvendor = 0x17aa, .config = AD1981_THINKPAD }, + { .pci_subvendor = 0x1014, .pci_subdevice = 0x0597, + .config = AD1981_THINKPAD }, /* Z60m/t */ + { .modelname = "basic", .config = AD1981_BASIC }, {} }; @@ -1464,9 +1437,7 @@ static int patch_ad1981(struct hda_codec *codec) codec->patch_ops = ad198x_patch_ops; /* override some parameters */ - board_config = snd_hda_check_board_config(codec, AD1981_MODELS, - ad1981_models, - ad1981_cfg_tbl); + board_config = snd_hda_check_board_config(codec, ad1981_cfg_tbl); switch (board_config) { case AD1981_HP: spec->mixers[0] = ad1981_hp_mixers; @@ -2594,14 +2565,15 @@ static int ad1988_auto_init(struct hda_codec *codec) /* */ -static const char *ad1988_models[AD1988_MODEL_LAST] = { - [AD1988_6STACK] = "6stack", - [AD1988_6STACK_DIG] = "6stack-dig", - [AD1988_3STACK] = "3stack", - [AD1988_3STACK_DIG] = "3stack-dig", - [AD1988_LAPTOP] = "laptop", - [AD1988_LAPTOP_DIG] = "laptop-dig", - [AD1988_AUTO] = "auto", +static struct hda_board_config ad1988_cfg_tbl[] = { + { .modelname = "6stack", .config = AD1988_6STACK }, + { .modelname = "6stack-dig", .config = AD1988_6STACK_DIG }, + { .modelname = "3stack", .config = AD1988_3STACK }, + { .modelname = "3stack-dig", .config = AD1988_3STACK_DIG }, + { .modelname = "laptop", .config = AD1988_LAPTOP }, + { .modelname = "laptop-dig", .config = AD1988_LAPTOP_DIG }, + { .modelname = "auto", .config = AD1988_AUTO }, + {} }; static int patch_ad1988(struct hda_codec *codec) @@ -2619,9 +2591,8 @@ static int patch_ad1988(struct hda_codec *codec) if (is_rev2(codec)) snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); - board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, - ad1988_models, NULL); - if (board_config < 0) { + board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl); + if (board_config < 0 || board_config >= AD1988_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); board_config = AD1988_AUTO; } diff --git a/trunk/sound/pci/hda/patch_cmedia.c b/trunk/sound/pci/hda/patch_cmedia.c index 5b9d3a31a1ae..d38ce22507ae 100644 --- a/trunk/sound/pci/hda/patch_cmedia.c +++ b/trunk/sound/pci/hda/patch_cmedia.c @@ -40,7 +40,6 @@ enum { CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ CMI_AUTO, /* let driver guess it */ - CMI_MODELS }; struct cmi_spec { @@ -604,17 +603,14 @@ static void cmi9880_free(struct hda_codec *codec) /* */ -static const char *cmi9880_models[CMI_MODELS] = { - [CMI_MINIMAL] = "minimal", - [CMI_MIN_FP] = "min_fp", - [CMI_FULL] = "full", - [CMI_FULL_DIG] = "full_dig", - [CMI_ALLOUT] = "allout", - [CMI_AUTO] = "auto", -}; - -static struct snd_pci_quirk cmi9880_cfg_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), +static struct hda_board_config cmi9880_cfg_tbl[] = { + { .modelname = "minimal", .config = CMI_MINIMAL }, + { .modelname = "min_fp", .config = CMI_MIN_FP }, + { .modelname = "full", .config = CMI_FULL }, + { .modelname = "full_dig", .config = CMI_FULL_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x813d, .config = CMI_FULL_DIG }, /* ASUS P5AD2 */ + { .modelname = "allout", .config = CMI_ALLOUT }, + { .modelname = "auto", .config = CMI_AUTO }, {} /* terminator */ }; @@ -637,9 +633,7 @@ static int patch_cmi9880(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS, - cmi9880_models, - cmi9880_cfg_tbl); + spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl); if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); spec->board_config = CMI_AUTO; /* try everything */ diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c deleted file mode 100644 index 73f4668238c6..000000000000 --- a/trunk/sound/pci/hda/patch_conexant.c +++ /dev/null @@ -1,1311 +0,0 @@ -/* - * HD audio interface patch for Conexant HDA audio codec - * - * Copyright (c) 2006 Pototskiy Akex - * Takashi Iwai - * Tobin Davis - * - * This driver 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 driver 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 -#include -#include -#include -#include -#include -#include "hda_codec.h" -#include "hda_local.h" - -#define CXT_PIN_DIR_IN 0x00 -#define CXT_PIN_DIR_OUT 0x01 -#define CXT_PIN_DIR_INOUT 0x02 -#define CXT_PIN_DIR_IN_NOMICBIAS 0x03 -#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04 - -#define CONEXANT_HP_EVENT 0x37 -#define CONEXANT_MIC_EVENT 0x38 - - - -struct conexant_spec { - - struct snd_kcontrol_new *mixers[5]; - int num_mixers; - - const struct hda_verb *init_verbs[5]; /* initialization verbs - * don't forget NULL - * termination! - */ - unsigned int num_init_verbs; - - /* playback */ - struct hda_multi_out multiout; /* playback set-up - * max_channels, dacs must be set - * dig_out_nid and hp_nid are optional - */ - unsigned int cur_eapd; - unsigned int need_dac_fix; - - /* capture */ - unsigned int num_adc_nids; - hda_nid_t *adc_nids; - hda_nid_t dig_in_nid; /* digital-in NID; optional */ - - /* capture source */ - const struct hda_input_mux *input_mux; - hda_nid_t *capsrc_nids; - unsigned int cur_mux[3]; - - /* channel model */ - const struct hda_channel_mode *channel_mode; - int num_channel_mode; - - /* PCM information */ - struct hda_pcm pcm_rec[2]; /* used in build_pcms() */ - - struct mutex amp_mutex; /* PCM volume/mute control mutex */ - unsigned int spdif_route; - - /* dynamic controls, init_verbs and input_mux */ - struct auto_pin_cfg autocfg; - unsigned int num_kctl_alloc, num_kctl_used; - struct snd_kcontrol_new *kctl_alloc; - struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; - -}; - -static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct conexant_spec *spec = codec->spec; - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); -} - -static int conexant_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_analog_prepare(codec, &spec->multiout, - stream_tag, - format, substream); -} - -static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct conexant_spec *spec = codec->spec; - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); -} - -/* - * Digital out - */ -static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct conexant_spec *spec = codec->spec; - return snd_hda_multi_out_dig_open(codec, &spec->multiout); -} - -static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct conexant_spec *spec = codec->spec; - return snd_hda_multi_out_dig_close(codec, &spec->multiout); -} - -/* - * Analog capture - */ -static int conexant_capture_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; - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - stream_tag, 0, format); - return 0; -} - -static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct conexant_spec *spec = codec->spec; - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - 0, 0, 0); - return 0; -} - - - -static struct hda_pcm_stream conexant_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = 0, /* fill later */ - .ops = { - .open = conexant_playback_pcm_open, - .prepare = conexant_playback_pcm_prepare, - .cleanup = conexant_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream conexant_pcm_analog_capture = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = 0, /* fill later */ - .ops = { - .prepare = conexant_capture_pcm_prepare, - .cleanup = conexant_capture_pcm_cleanup - }, -}; - - -static struct hda_pcm_stream conexant_pcm_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = 0, /* fill later */ - .ops = { - .open = conexant_dig_playback_pcm_open, - .close = conexant_dig_playback_pcm_close - }, -}; - -static struct hda_pcm_stream conexant_pcm_digital_capture = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - /* NID is set in alc_build_pcms */ -}; - -static int conexant_build_pcms(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - struct hda_pcm *info = spec->pcm_rec; - - codec->num_pcms = 1; - codec->pcm_info = info; - - info->name = "CONEXANT Analog"; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = - spec->multiout.max_channels; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = - spec->multiout.dac_nids[0]; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_analog_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; - - if (spec->multiout.dig_out_nid) { - info++; - codec->num_pcms++; - info->name = "Conexant Digital"; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = - conexant_pcm_digital_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = - spec->multiout.dig_out_nid; - if (spec->dig_in_nid) { - info->stream[SNDRV_PCM_STREAM_CAPTURE] = - conexant_pcm_digital_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = - spec->dig_in_nid; - } - } - - return 0; -} - -static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - - return snd_hda_input_mux_info(spec->input_mux, uinfo); -} - -static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; - return 0; -} - -static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - spec->capsrc_nids[adc_idx], - &spec->cur_mux[adc_idx]); -} - -static int conexant_init(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->num_init_verbs; i++) - snd_hda_sequence_write(codec, spec->init_verbs[i]); - return 0; -} - -static void conexant_free(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - unsigned int i; - - if (spec->kctl_alloc) { - for (i = 0; i < spec->num_kctl_used; i++) - kfree(spec->kctl_alloc[i].name); - kfree(spec->kctl_alloc); - } - - kfree(codec->spec); -} - -#ifdef CONFIG_PM -static int conexant_resume(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - int i; - - codec->patch_ops.init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - return 0; -} -#endif - -static int conexant_build_controls(struct hda_codec *codec) -{ - struct conexant_spec *spec = codec->spec; - unsigned int i; - int err; - - for (i = 0; i < spec->num_mixers; i++) { - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); - if (err < 0) - return err; - } - if (spec->multiout.dig_out_nid) { - err = snd_hda_create_spdif_out_ctls(codec, - spec->multiout.dig_out_nid); - if (err < 0) - return err; - } - if (spec->dig_in_nid) { - err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid); - if (err < 0) - return err; - } - return 0; -} - -static struct hda_codec_ops conexant_patch_ops = { - .build_controls = conexant_build_controls, - .build_pcms = conexant_build_pcms, - .init = conexant_init, - .free = conexant_free, -#ifdef CONFIG_PM - .resume = conexant_resume, -#endif -}; - -/* - * EAPD control - * the private value = nid | (invert << 8) - */ - -static int conexant_eapd_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 conexant_eapd_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - int invert = (kcontrol->private_value >> 8) & 1; - if (invert) - ucontrol->value.integer.value[0] = !spec->cur_eapd; - else - ucontrol->value.integer.value[0] = spec->cur_eapd; - return 0; -} - -static int conexant_eapd_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - int invert = (kcontrol->private_value >> 8) & 1; - hda_nid_t nid = kcontrol->private_value & 0xff; - unsigned int eapd; - eapd = ucontrol->value.integer.value[0]; - if (invert) - eapd = !eapd; - if (eapd == spec->cur_eapd && !codec->in_resume) - return 0; - spec->cur_eapd = eapd; - snd_hda_codec_write(codec, nid, - 0, AC_VERB_SET_EAPD_BTLENABLE, - eapd ? 0x02 : 0x00); - return 1; -} - -/* controls for test mode */ -#ifdef CONFIG_SND_DEBUG - -static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, - spec->num_channel_mode); -} - -static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, - spec->num_channel_mode, - spec->multiout.max_channels); -} - -static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, - spec->num_channel_mode, - &spec->multiout.max_channels); - if (err >= 0 && spec->need_dac_fix) - spec->multiout.num_dacs = spec->multiout.max_channels / 2; - return err; -} - -#define CXT_PIN_MODE(xname, nid, dir) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = conexant_ch_mode_info, \ - .get = conexant_ch_mode_get, \ - .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) } - -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 /* CONFIG_SND_DEBUG */ - -/* Conexant 5045 specific */ - -static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; -static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; -static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; -#define CXT5045_SPDIF_OUT 0x13 - -static struct hda_channel_mode cxt5045_modes[1] = { - { 2, NULL }, -}; - -static struct hda_input_mux cxt5045_capture_source = { - .num_items = 2, - .items = { - { "ExtMic", 0x1 }, - { "LineIn", 0x2 }, - } -}; - -/* turn on/off EAPD (+ mute HP) as a master switch */ -static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - - if (!conexant_eapd_put(kcontrol, ucontrol)) - return 0; - - /* toggle HP mute appropriately */ - snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - return 1; -} - -/* bind volumes of both NID 0x10 and 0x11 */ -static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} - - -/* mute internal speaker if HP is plugged */ -static void cxt5045_hp_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x11, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -/* unsolicited event for HP jack sensing */ -static void cxt5045_hp_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - res >>= 26; - switch (res) { - case CONEXANT_HP_EVENT: - cxt5045_hp_automute(codec); - break; - } -} - -static struct snd_kcontrol_new cxt5045_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", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x02, HDA_INPUT), - { - .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 = cxt5045_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = conexant_eapd_info, - .get = conexant_eapd_get, - .put = cxt5045_hp_master_sw_put, - .private_value = 0x11, - }, - - {} -}; - -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 }, - /* HP, Amp */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {0x1A, AC_VERB_SET_CONNECT_SEL,0x01}, - {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}, - /* Record selector: Front mic */ - {0x14, AC_VERB_SET_CONNECT_SEL,0x03}, - {0x17, 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, 0x0 }, /* default on */ - { } /* end */ -}; - -#ifdef CONFIG_SND_DEBUG -/* Test configuration for debugging, modelled after the ALC260 test - * configuration. - */ -static struct hda_input_mux cxt5045_test_capture_source = { - .num_items = 5, - .items = { - { "MIXER", 0x0 }, - { "MIC1 pin", 0x1 }, - { "LINE1 pin", 0x2 }, - { "HP-OUT pin", 0x3 }, - { "CD pin", 0x4 }, - }, -}; - -static struct snd_kcontrol_new cxt5045_test_mixer[] = { - - /* Output controls */ - HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x19, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("OutAmp-1 Switch", 0x19,0x00, HDA_OUTPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), - - /* Modes for retasking pin widgets */ - CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), - CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT), - - /* 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), - - /* Controls for GPIO pins, assuming they exist and are configured as outputs */ - CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), -#if 0 /* limit this to one GPIO pin for now */ - 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), -#endif - CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x13, 0x01), - - HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .info = conexant_mux_enum_info, - .get = conexant_mux_enum_get, - .put = conexant_mux_enum_put, - }, - - { } /* end */ -}; - -static struct hda_verb cxt5045_test_init_verbs[] = { - /* Enable all GPIOs as outputs with an initial value of 0 */ - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, - - /* 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_OUT}, - - /* Disable digital (SPDIF) pins initially, but users can enable - * them via a mixer switch. In the case of SPDIF-out, this initverb - * payload also sets the generation to 0, output to be in "consumer" - * PCM format, copyright asserted, no pre-emphasis and no validity - * control. - */ - {0x13, AC_VERB_SET_DIGI_CONVERT_1, 0}, - - /* Start with output sum widgets muted and their output gains at min */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - - /* Unmute retasking pin widget output buffers since the default - * state appears to be output. As the pin mode is changed by the - * user the pin mode control will take care of enabling the pin's - * input/output buffers as needed. - */ - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - /* Mute capture amp left and right */ - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - - /* Set ADC connection select to match default mixer setting (mic1 - * pin) - */ - {0x1a, 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 */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ - - { } -}; -#endif - - -/* initialize jack-sensing, too */ -static int cxt5045_init(struct hda_codec *codec) -{ - conexant_init(codec); - cxt5045_hp_automute(codec); - return 0; -} - - -enum { - CXT5045_LAPTOP, /* Laptops w/ EAPD support */ -#ifdef CONFIG_SND_DEBUG - CXT5045_TEST, -#endif - CXT5045_MODELS -}; - -static const char *cxt5045_models[CXT5045_MODELS] = { - [CXT5045_LAPTOP] = "laptop", -#ifdef CONFIG_SND_DEBUG - [CXT5045_TEST] = "test", -#endif -}; - -static struct snd_pci_quirk cxt5045_cfg_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), - {} -}; - -static int patch_cxt5045(struct hda_codec *codec) -{ - struct conexant_spec *spec; - int board_config; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids); - spec->multiout.dac_nids = cxt5045_dac_nids; - spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT; - spec->num_adc_nids = 1; - spec->adc_nids = cxt5045_adc_nids; - spec->capsrc_nids = cxt5045_capsrc_nids; - spec->input_mux = &cxt5045_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = cxt5045_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = cxt5045_init_verbs; - spec->spdif_route = 0; - spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes), - spec->channel_mode = cxt5045_modes, - - - 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: - spec->input_mux = &cxt5045_capture_source; - spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5045_init_verbs; - spec->mixers[0] = cxt5045_mixers; - codec->patch_ops.init = cxt5045_init; - break; -#ifdef CONFIG_SND_DEBUG - case CXT5045_TEST: - spec->input_mux = &cxt5045_test_capture_source; - spec->mixers[0] = cxt5045_test_mixer; - spec->init_verbs[0] = cxt5045_test_init_verbs; -#endif - } - return 0; -} - - -/* Conexant 5047 specific */ - -static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; -static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; -static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; -#define CXT5047_SPDIF_OUT 0x11 - -static struct hda_channel_mode cxt5047_modes[1] = { - { 2, NULL }, -}; - -static struct hda_input_mux cxt5047_capture_source = { - .num_items = 2, - .items = { - { "ExtMic", 0x1 }, - { "IntMic", 0x2 }, - } -}; - -static struct hda_input_mux cxt5047_hp_capture_source = { - .num_items = 1, - .items = { - { "ExtMic", 0x1 }, - } -}; - -/* turn on/off EAPD (+ mute HP) as a master switch */ -static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct conexant_spec *spec = codec->spec; - - if (!conexant_eapd_put(kcontrol, ucontrol)) - return 0; - - /* toggle HP mute appropriately */ - snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, - 0x80, spec->cur_eapd ? 0 : 0x80); - return 1; -} - -#if 0 -/* bind volumes of both NID 0x13 and 0x1d */ -static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - change |= snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, - 0x7f, valp[0] & 0x7f); - snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, - 0x7f, valp[1] & 0x7f); - return change; -} -#endif - -/* mute internal speaker if HP is plugged */ -static void cxt5047_hp_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x13, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -/* toggle input of built-in and mic jack appropriately */ -static void cxt5047_hp_automic(struct hda_codec *codec) -{ - static struct hda_verb mic_jack_on[] = { - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} - }; - static struct hda_verb mic_jack_off[] = { - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {} - }; - unsigned int present; - - present = snd_hda_codec_read(codec, 0x08, 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); -} - -/* unsolicited event for HP jack sensing */ -static void cxt5047_hp_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - res >>= 26; - switch (res) { - case CONEXANT_HP_EVENT: - cxt5047_hp_automute(codec); - break; - case CONEXANT_MIC_EVENT: - cxt5047_hp_automic(codec); - break; - } -} - -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("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("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = conexant_eapd_info, - .get = conexant_eapd_get, - .put = cxt5047_hp_master_sw_put, - .private_value = 0x13, - }, - - {} -}; - -static struct snd_kcontrol_new cxt5047_hp_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("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("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = conexant_eapd_info, - .get = conexant_eapd_get, - .put = cxt5047_hp_master_sw_put, - .private_value = 0x13, - }, - { } /* end */ -}; - -static struct hda_verb cxt5047_init_verbs[] = { - /* Line in, Mic, Built-in Mic */ - {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 */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {0x1A, AC_VERB_SET_CONNECT_SEL,0x03}, - {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}, - /* Record selector: Front 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}, - /* SPDIF route: PCM */ - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, - { } /* end */ -}; - -/* configuration for Toshiba Laptops */ -static struct hda_verb cxt5047_toshiba_init_verbs[] = { - {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0 }, /* default on */ - /* pin sensing on HP and Mic jacks */ - {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, - {} -}; - -/* configuration for HP Laptops */ -static struct hda_verb cxt5047_hp_init_verbs[] = { - /* pin sensing on HP and Mic jacks */ - {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, - {} -}; - -/* Test configuration for debugging, modelled after the ALC260 test - * configuration. - */ -#ifdef CONFIG_SND_DEBUG -static struct hda_input_mux cxt5047_test_capture_source = { - .num_items = 5, - .items = { - { "MIXER", 0x0 }, - { "LINE1 pin", 0x1 }, - { "MIC1 pin", 0x2 }, - { "MIC2 pin", 0x3 }, - { "CD pin", 0x4 }, - }, -}; - -static struct snd_kcontrol_new cxt5047_test_mixer[] = { - - /* Output only controls */ - HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x00, HDA_OUTPUT), - HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x00, HDA_OUTPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT), - - /* Modes for retasking pin widgets */ - CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT), - CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT), - - /* Loopback mixer controls */ - HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("LINE Playback Volume", 0x19, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("LINE Playback Switch", 0x19, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT), - -#if 0 - /* 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), -#endif - CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01), - - HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .info = conexant_mux_enum_info, - .get = conexant_mux_enum_get, - .put = conexant_mux_enum_put, - }, - - { } /* end */ -}; - -static struct hda_verb cxt5047_test_init_verbs[] = { - /* Enable all GPIOs as outputs with an initial value of 0 */ - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, - - /* Enable retasking pins as output, initially without power amp */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x13, 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 - * payload also sets the generation to 0, output to be in "consumer" - * PCM format, copyright asserted, no pre-emphasis and no validity - * control. - */ - {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, - - /* Ensure mic1, mic2, line1 pin widgets take input from the - * OUT1 sum bus when acting as an output. - */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0}, - - /* Start with output sum widgets muted and their output gains at min */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - - /* Unmute retasking pin widget output buffers since the default - * state appears to be output. As the pin mode is changed by the - * user the pin mode control will take care of enabling the pin's - * input/output buffers as needed. - */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - /* Mute capture amp left and right */ - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - - /* Set ADC connection select to match default mixer setting (mic1 - * pin) - */ - {0x12, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ - - { } -}; -#endif - - -/* initialize jack-sensing, too */ -static int cxt5047_hp_init(struct hda_codec *codec) -{ - conexant_init(codec); - cxt5047_hp_automute(codec); - cxt5047_hp_automic(codec); - return 0; -} - - -enum { - CXT5047_LAPTOP, /* Laptops w/o EAPD support */ - CXT5047_LAPTOP_HP, /* Some HP laptops */ - CXT5047_LAPTOP_EAPD, /* Laptops with EAPD support */ -#ifdef CONFIG_SND_DEBUG - CXT5047_TEST, -#endif - CXT5047_MODELS -}; - -static const char *cxt5047_models[CXT5047_MODELS] = { - [CXT5047_LAPTOP] = "laptop", - [CXT5047_LAPTOP_HP] = "laptop-hp", - [CXT5047_LAPTOP_EAPD] = "laptop-eapd", -#ifdef CONFIG_SND_DEBUG - [CXT5047_TEST] = "test", -#endif -}; - -static struct snd_pci_quirk cxt5047_cfg_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x30a0, "HP DV1000", CXT5047_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), - SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), - {} -}; - -static int patch_cxt5047(struct hda_codec *codec) -{ - struct conexant_spec *spec; - int board_config; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids); - spec->multiout.dac_nids = cxt5047_dac_nids; - spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT; - spec->num_adc_nids = 1; - spec->adc_nids = cxt5047_adc_nids; - spec->capsrc_nids = cxt5047_capsrc_nids; - spec->input_mux = &cxt5047_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = cxt5047_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = cxt5047_init_verbs; - spec->spdif_route = 0; - spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes), - spec->channel_mode = cxt5047_modes, - - codec->patch_ops = conexant_patch_ops; - codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; - - board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, - cxt5047_models, - cxt5047_cfg_tbl); - switch (board_config) { - case CXT5047_LAPTOP: - break; - case CXT5047_LAPTOP_HP: - spec->input_mux = &cxt5047_hp_capture_source; - spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5047_hp_init_verbs; - spec->mixers[0] = cxt5047_hp_mixers; - codec->patch_ops.init = cxt5047_hp_init; - break; - case CXT5047_LAPTOP_EAPD: - spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5047_toshiba_init_verbs; - break; -#ifdef CONFIG_SND_DEBUG - case CXT5047_TEST: - spec->input_mux = &cxt5047_test_capture_source; - spec->mixers[0] = cxt5047_test_mixer; - spec->init_verbs[0] = cxt5047_test_init_verbs; -#endif - } - return 0; -} - -struct hda_codec_preset snd_hda_preset_conexant[] = { - { .id = 0x14f15045, .name = "CXT5045", .patch = patch_cxt5045 }, - { .id = 0x14f15047, .name = "CXT5047", .patch = patch_cxt5047 }, - {} /* terminator */ -}; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 145682b78071..4e0c3c1b908b 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -32,10 +32,6 @@ #include "hda_codec.h" #include "hda_local.h" -#define ALC880_FRONT_EVENT 0x01 -#define ALC880_DCVOL_EVENT 0x02 -#define ALC880_HP_EVENT 0x04 -#define ALC880_MIC_EVENT 0x08 /* ALC880 board config type */ enum { @@ -52,10 +48,7 @@ enum { ALC880_ASUS_DIG, ALC880_ASUS_W1V, ALC880_ASUS_DIG2, - ALC880_FUJITSU, ALC880_UNIWILL_DIG, - ALC880_UNIWILL, - ALC880_UNIWILL_P53, ALC880_CLEVO, ALC880_TCL_S700, ALC880_LG, @@ -84,12 +77,8 @@ enum { /* ALC262 models */ enum { ALC262_BASIC, - ALC262_HIPPO, - ALC262_HIPPO_1, ALC262_FUJITSU, ALC262_HP_BPC, - ALC262_HP_BPC_D7000_WL, - ALC262_HP_BPC_D7000_WF, ALC262_BENQ_ED8, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ @@ -102,30 +91,16 @@ enum { ALC861_3ST_DIG, ALC861_6ST_DIG, ALC861_UNIWILL_M31, - ALC861_TOSHIBA, - ALC861_ASUS, - ALC861_ASUS_LAPTOP, ALC861_AUTO, ALC861_MODEL_LAST, }; -/* ALC861-VD models */ -enum { - ALC660VD_3ST, - ALC861VD_3ST, - ALC861VD_3ST_DIG, - ALC861VD_6ST_DIG, - ALC861VD_AUTO, - ALC861VD_MODEL_LAST, -}; - /* ALC882 models */ enum { ALC882_3ST_DIG, ALC882_6ST_DIG, ALC882_ARIMA, ALC882_AUTO, - ALC885_MACPRO, ALC882_MODEL_LAST, }; @@ -135,12 +110,8 @@ enum { ALC883_3ST_6ch_DIG, ALC883_3ST_6ch, ALC883_6ST_DIG, - ALC883_TARGA_DIG, - ALC883_TARGA_2ch_DIG, ALC888_DEMO_BOARD, ALC883_ACER, - ALC883_MEDION, - ALC883_LAPTOP_EAPD, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -1044,60 +1015,6 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { { } /* end */ }; -/* Uniwill */ -static struct snd_kcontrol_new alc880_uniwill_mixer[] = { - HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("HPhone 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_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 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_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), - { - .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 snd_kcontrol_new alc880_fujitsu_mixer[] = { - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 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("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { - HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("HPhone 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_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - /* * build control elements */ @@ -1331,159 +1248,6 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = { { } }; -/* - * Uniwill pin configuration: - * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, - * line = 0x1a - */ -static struct hda_verb alc880_uniwill_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, 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}, - /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ - /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, - - { } -}; - -/* -* Uniwill P53 -* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, - */ -static struct hda_verb alc880_uniwill_p53_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, 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}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, - - { } -}; - -static struct hda_verb alc880_beep_init_verbs[] = { - { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc880_uniwill_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - - 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)); -} - -static void alc880_uniwill_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - /* 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); -} - -static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - - snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); -} - -static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f; - - snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, - 0x7f, present); - snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, - 0x7f, present); - - snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, - 0x7f, present); - snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, - 0x7f, present); - -} -static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - /* Looks like the unsol event is incompatible with the standard - * definition. 4bit tag is placed at 28 bit! - */ - if ((res >> 28) == ALC880_HP_EVENT) - alc880_uniwill_p53_hp_automute(codec); - if ((res >> 28) == ALC880_DCVOL_EVENT) - alc880_uniwill_p53_dcvol_automute(codec); -} - /* FIXME! */ /* * F1734 pin configuration: @@ -2361,112 +2125,159 @@ static struct hda_verb alc880_test_init_verbs[] = { /* */ -static const char *alc880_models[ALC880_MODEL_LAST] = { - [ALC880_3ST] = "3stack", - [ALC880_TCL_S700] = "tcl", - [ALC880_3ST_DIG] = "3stack-digout", - [ALC880_CLEVO] = "clevo", - [ALC880_5ST] = "5stack", - [ALC880_5ST_DIG] = "5stack-digout", - [ALC880_W810] = "w810", - [ALC880_Z71V] = "z71v", - [ALC880_6ST] = "6stack", - [ALC880_6ST_DIG] = "6stack-digout", - [ALC880_ASUS] = "asus", - [ALC880_ASUS_W1V] = "asus-w1v", - [ALC880_ASUS_DIG] = "asus-dig", - [ALC880_ASUS_DIG2] = "asus-dig2", - [ALC880_UNIWILL_DIG] = "uniwill", - [ALC880_UNIWILL_P53] = "uniwill-p53", - [ALC880_FUJITSU] = "fujitsu", - [ALC880_F1734] = "F1734", - [ALC880_LG] = "lg", - [ALC880_LG_LW] = "lg-lw", +static struct hda_board_config alc880_cfg_tbl[] = { + /* Back 3 jack, front 2 jack */ + { .modelname = "3stack", .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, + /* TCL S700 */ + { .modelname = "tcl", .config = ALC880_TCL_S700 }, + { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 }, + + /* Back 3 jack, front 2 jack (Internal add Aux-In) */ + { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST }, + + /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ + { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, + + /* Clevo laptops */ + { .modelname = "clevo", .config = ALC880_CLEVO }, + { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, + .config = ALC880_CLEVO }, /* Clevo m520G NB */ + { .pci_subvendor = 0x1558, .pci_subdevice = 0x0660, + .config = ALC880_CLEVO }, /* Clevo m665n */ + + /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG }, + + /* Back 5 jack, front 2 jack */ + { .modelname = "5stack", .config = ALC880_5ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST }, + { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST }, + + /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */ + { .modelname = "5stack-digout", .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, + { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, + .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ + /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ + { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, + /* note subvendor = 0 below */ + /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ + + { .modelname = "w810", .config = ALC880_W810 }, + { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, + + { .modelname = "z71v", .config = ALC880_Z71V }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, + + { .modelname = "6stack", .config = ALC880_6ST }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST }, + { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ + { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */ + + { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, + { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ + { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ + { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */ + + { .modelname = "asus", .config = ALC880_ASUS }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c2, .config = ALC880_ASUS_DIG }, /* Asus W6A */ + { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, + { .modelname = "asus-w1v", .config = ALC880_ASUS_W1V }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, + { .modelname = "asus-dig", .config = ALC880_ASUS_DIG }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ + { .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 }, + { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, + + { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, + { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG }, + + { .modelname = "F1734", .config = ALC880_F1734 }, + { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, + { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, + + { .modelname = "lg", .config = ALC880_LG }, + { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, + { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG }, + + { .modelname = "lg-lw", .config = ALC880_LG_LW }, + { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW }, + { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW }, + #ifdef CONFIG_SND_DEBUG - [ALC880_TEST] = "test", + { .modelname = "test", .config = ALC880_TEST }, #endif - [ALC880_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc880_cfg_tbl[] = { - /* Broken BIOS configuration */ - SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), - SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), - - SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), - SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), - SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), - SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), - SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), - - SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), - SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), - - SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), - SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), - /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ - SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS), - SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), - SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), - SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), - SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), - - SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), - SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), - SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), - SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), - SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), - SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), - SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), - SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), - SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), - SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), - SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), - SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), - - SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), - SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), - SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), - SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), - - SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), - SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), - SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), - - SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), - SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), - SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), - SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), - - SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), - SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), - SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), - SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), - SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), + { .modelname = "auto", .config = ALC880_AUTO }, {} }; @@ -2627,8 +2438,7 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_UNIWILL_DIG] = { .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_pin_asus_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2637,46 +2447,6 @@ static struct alc_config_preset alc880_presets[] = { .need_dac_fix = 1, .input_mux = &alc880_capture_source, }, - [ALC880_UNIWILL] = { - .mixers = { alc880_uniwill_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_uniwill_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), - .dac_nids = alc880_asus_dac_nids, - .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), - .channel_mode = alc880_threestack_modes, - .need_dac_fix = 1, - .input_mux = &alc880_capture_source, - .unsol_event = alc880_uniwill_unsol_event, - .init_hook = alc880_uniwill_automute, - }, - [ALC880_UNIWILL_P53] = { - .mixers = { alc880_uniwill_p53_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_uniwill_p53_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), - .dac_nids = alc880_asus_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), - .channel_mode = alc880_threestack_modes, - .input_mux = &alc880_capture_source, - .unsol_event = alc880_uniwill_p53_unsol_event, - .init_hook = alc880_uniwill_p53_hp_automute, - }, - [ALC880_FUJITSU] = { - .mixers = { alc880_fujitsu_mixer, - alc880_pcbeep_mixer, }, - .init_verbs = { alc880_volume_init_verbs, - alc880_uniwill_p53_init_verbs, - alc880_beep_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_dac_nids), - .dac_nids = alc880_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), - .channel_mode = alc880_2_jack_modes, - .input_mux = &alc880_capture_source, - .unsol_event = alc880_uniwill_p53_unsol_event, - .init_hook = alc880_uniwill_p53_hp_automute, - }, [ALC880_CLEVO] = { .mixers = { alc880_three_stack_mixer }, .init_verbs = { alc880_volume_init_verbs, @@ -3071,10 +2841,8 @@ static int patch_alc880(struct hda_codec *codec) codec->spec = spec; - board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, - alc880_models, - alc880_cfg_tbl); - if (board_config < 0) { + board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); + if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for ALC880, " "trying auto-probe from BIOS...\n"); board_config = ALC880_AUTO; @@ -3322,20 +3090,11 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { * and the output jack. If this turns out to be the case for all such * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT * to ALC_PIN_DIR_INOUT_NOMICBIAS. - * - * The C20x Tablet series have a mono internal speaker which is controlled - * via the chip's Mono sum widget and pin complex, so include the necessary - * controls for such models. On models without a "mono speaker" the control - * won't do anything. */ static struct snd_kcontrol_new alc260_acer_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, - HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, - HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), @@ -3650,11 +3409,11 @@ static struct hda_verb alc260_acer_init_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, /* Line In jack is connected to Line1 pin */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, /* Ensure all other unused pins are disabled and muted. */ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, + {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, @@ -3682,8 +3441,6 @@ static struct hda_verb alc260_acer_init_verbs[] = { /* 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}, /* Unmute Mic1 and Line1 pin widget input buffers since they start as * inputs. If the pin mode is changed by the user the pin mode control * will take care of enabling the pin's input/output buffers as needed. @@ -4171,33 +3928,33 @@ static void alc260_auto_init(struct hda_codec *codec) /* * ALC260 configurations */ -static const char *alc260_models[ALC260_MODEL_LAST] = { - [ALC260_BASIC] = "basic", - [ALC260_HP] = "hp", - [ALC260_HP_3013] = "hp-3013", - [ALC260_FUJITSU_S702X] = "fujitsu", - [ALC260_ACER] = "acer", +static struct hda_board_config alc260_cfg_tbl[] = { + { .modelname = "basic", .config = ALC260_BASIC }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, + .config = ALC260_BASIC }, /* Sony VAIO */ + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc, + .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */ + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd, + .config = ALC260_BASIC }, /* Sony VAIO */ + { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, + .config = ALC260_BASIC }, /* CTL Travel Master U553W */ + { .modelname = "hp", .config = ALC260_HP }, + { .modelname = "hp-3013", .config = ALC260_HP_3013 }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP_3013 }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, + { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, + { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, + { .modelname = "acer", .config = ALC260_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, #ifdef CONFIG_SND_DEBUG - [ALC260_TEST] = "test", + { .modelname = "test", .config = ALC260_TEST }, #endif - [ALC260_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc260_cfg_tbl[] = { - SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), - SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), - SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), - SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), - SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), - SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), - SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), - SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), - 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), + { .modelname = "auto", .config = ALC260_AUTO }, {} }; @@ -4296,10 +4053,8 @@ static int patch_alc260(struct hda_codec *codec) codec->spec = spec; - board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, - alc260_models, - alc260_cfg_tbl); - if (board_config < 0) { + board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); + if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " "trying auto-probe from BIOS...\n"); board_config = ALC260_AUTO; @@ -4452,10 +4207,8 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { 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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, 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), @@ -4560,100 +4313,6 @@ static struct hda_verb alc882_eapd_verbs[] = { { } }; -/* Mac Pro test */ -static struct snd_kcontrol_new alc882_macpro_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT), - { } /* end */ -}; - -static struct hda_verb alc882_macpro_init_verbs[] = { - /* Front mixer: unmute input/output amp left and right (volume = 0) */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Front Pin: output 0 (0x0c) */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* 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}, - /* Speaker: output */ - {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, 0x04}, - /* Headphone output (output 0 - 0x0c) */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Input mixer3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* ADC1: mute amp left and right */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* ADC2: mute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* ADC3: mute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, - - { } -}; -static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) -{ - unsigned int gpiostate, gpiomask, gpiodir; - - gpiostate = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_DATA, 0); - - if (!muted) - gpiostate |= (1 << pin); - else - gpiostate &= ~(1 << pin); - - gpiomask = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_MASK, 0); - gpiomask |= (1 << pin); - - gpiodir = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_DIRECTION, 0); - gpiodir |= (1 << pin); - - - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, gpiomask); - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpiodir); - - msleep(1); - - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, gpiostate); -} - /* * generic initialization of ADC, input mixers and output mixers */ @@ -4776,20 +4435,19 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = { /* * configuration and preset */ -static const char *alc882_models[ALC882_MODEL_LAST] = { - [ALC882_3ST_DIG] = "3stack-dig", - [ALC882_6ST_DIG] = "6stack-dig", - [ALC882_ARIMA] = "arima", - [ALC885_MACPRO] = "macpro", - [ALC882_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc882_cfg_tbl[] = { - SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), - 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), +static struct hda_board_config alc882_cfg_tbl[] = { + { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, + { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, + { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, + .config = ALC882_6ST_DIG }, /* MSI */ + { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, + .config = ALC882_6ST_DIG }, /* Foxconn */ + { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, + .config = ALC882_6ST_DIG }, /* ECS to Intel*/ + { .modelname = "arima", .config = ALC882_ARIMA }, + { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054, + .config = ALC882_ARIMA }, /* Arima W820Di1 */ + { .modelname = "auto", .config = ALC882_AUTO }, {} }; @@ -4826,17 +4484,6 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_sixstack_modes, .input_mux = &alc882_capture_source, }, - [ALC885_MACPRO] = { - .mixers = { alc882_macpro_mixer }, - .init_verbs = { alc882_macpro_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .input_mux = &alc882_capture_source, - }, }; @@ -4937,9 +4584,7 @@ static int patch_alc882(struct hda_codec *codec) codec->spec = spec; - board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, - alc882_models, - alc882_cfg_tbl); + board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for ALC882, " @@ -4964,11 +4609,6 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - if (board_config == ALC885_MACPRO) { - alc882_gpio_mute(codec, 0, 0); - alc882_gpio_mute(codec, 1, 0); - } - spec->stream_name_analog = "ALC882 Analog"; spec->stream_analog_playback = &alc882_pcm_analog_playback; spec->stream_analog_capture = &alc882_pcm_analog_capture; @@ -5127,13 +4767,6 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { { 8, alc883_sixstack_ch8_init }, }; -static struct hda_verb alc883_medion_eapd_verbs[] = { - /* eanable EAPD on medion laptop */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, - { } -}; - /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ @@ -5155,10 +4788,8 @@ static struct snd_kcontrol_new alc883_base_mixer[] = { 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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, 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), @@ -5187,10 +4818,8 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, 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), @@ -5225,10 +4854,8 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 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("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, 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), @@ -5248,101 +4875,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_fivestack_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), - 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_VOLUME("Mic Boost", 0x18, 0, 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_VOLUME("Front Mic Boost", 0x19, 0, 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", 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_tagra_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 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("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .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), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front 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("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("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .put = alc883_mux_enum_put, - }, - { } /* end */ -}; - static struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -5431,45 +4963,6 @@ static struct hda_verb alc883_init_verbs[] = { { } }; -static struct hda_verb alc883_tagra_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ - {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}, - - { } /* end */ -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc883_tagra_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - 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); -} - -static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc883_tagra_automute(codec); -} - /* * generic initialization of ADC, input mixers and output mixers */ @@ -5564,42 +5057,32 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = { /* * configuration and preset */ -static const char *alc883_models[ALC883_MODEL_LAST] = { - [ALC883_3ST_2ch_DIG] = "3stack-dig", - [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", - [ALC883_3ST_6ch] = "3stack-6ch", - [ALC883_6ST_DIG] = "6stack-dig", - [ALC883_TARGA_DIG] = "targa-dig", - [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", - [ALC888_DEMO_BOARD] = "6stack-dig-demo", - [ALC883_ACER] = "acer", - [ALC883_MEDION] = "medion", - [ALC883_LAPTOP_EAPD] = "laptop-eapd", - [ALC883_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc883_cfg_tbl[] = { - SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), - 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(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), - 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), +static struct hda_board_config alc883_cfg_tbl[] = { + { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, + { .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG }, + { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, + .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ + { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch }, + { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, + .config = ALC883_3ST_6ch }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601, + .config = ALC883_3ST_6ch }, /* D102GGC */ + { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, + { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, + .config = ALC883_6ST_DIG }, /* MSI */ + { .pci_subvendor = 0x1462, .pci_subdevice = 0x7280, + .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */ + { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, + .config = ALC883_6ST_DIG }, /* Foxconn */ + { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, + { .modelname = "acer", .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, + .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102, + .config = ALC883_ACER }, + { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f, + .config = ALC883_ACER }, + { .modelname = "auto", .config = ALC883_AUTO }, {} }; @@ -5656,35 +5139,6 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, }, - [ALC883_TARGA_DIG] = { - .mixers = { alc883_tagra_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - .unsol_event = alc883_tagra_unsol_event, - .init_hook = alc883_tagra_automute, - }, - [ALC883_TARGA_2ch_DIG] = { - .mixers = { alc883_tagra_2ch_mixer}, - .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .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_capture_source, - .unsol_event = alc883_tagra_unsol_event, - .init_hook = alc883_tagra_automute, - }, [ALC888_DEMO_BOARD] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5715,31 +5169,6 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, }, - [ALC883_MEDION] = { - .mixers = { alc883_fivestack_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, - alc883_medion_eapd_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_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_LAPTOP_EAPD] = { - .mixers = { alc883_base_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc882_eapd_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_capture_source, - }, }; @@ -5848,10 +5277,8 @@ static int patch_alc883(struct hda_codec *codec) codec->spec = spec; - board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, - alc883_models, - alc883_cfg_tbl); - if (board_config < 0) { + board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); + if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for ALC883, " "trying auto-probe from BIOS...\n"); board_config = ALC883_AUTO; @@ -5928,24 +5355,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_hippo1_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 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, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ - /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - { } /* end */ -}; - static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -5968,30 +5377,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, 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("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), - { } /* end */ -}; - -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { - HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - #define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer @@ -6074,103 +5459,6 @@ static struct hda_verb alc262_init_verbs[] = { { } }; -static struct hda_verb alc262_hippo_unsol_verbs[] = { - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static struct hda_verb alc262_hippo1_unsol_verbs[] = { - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -/* mute/unmute internal speaker according to the hp jack and mute state */ -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) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; - spec->sense_updated = 1; - } - if (spec->jack_present) { - /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, 0x80); - } else { - /* unmute internal speaker if necessary */ - mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - } -} - -/* unsolicited event for HP jack sensing */ -static void alc262_hippo_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc262_hippo_automute(codec, 1); -} - -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) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; - spec->sense_updated = 1; - } - if (spec->jack_present) { - /* mute internal speaker */ - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, 0x80); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, 0x80); - } else { - /* unmute internal speaker if necessary */ - mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0); - snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, mute & 0x80); - } -} - -/* unsolicited event for HP jack sensing */ -static void alc262_hippo1_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc262_hippo1_automute(codec, 1); -} - /* * fujitsu model * 0x14 = headphone/spdif-out, 0x15 = internal speaker @@ -6521,105 +5809,11 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { { } }; -static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { - /* - * Unmute ADC0-2 and set the default input to mic-in - */ - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {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)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, - /* - * Set up output mixers (0x0c - 0x0e) - */ - /* set vol=0 to output mixers */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* set up input amps for analog loopback */ - /* Amp Indices: DAC = 0, mixer = 1 */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ - - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - - /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ - /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, - /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, - /* Input mixer3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, - /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, - - { } -}; - -/* pcm configuration: identiacal with ALC880 */ -#define alc262_pcm_analog_playback alc880_pcm_analog_playback -#define alc262_pcm_analog_capture alc880_pcm_analog_capture -#define alc262_pcm_digital_playback alc880_pcm_digital_playback -#define alc262_pcm_digital_capture alc880_pcm_digital_capture +/* pcm configuration: identiacal with ALC880 */ +#define alc262_pcm_analog_playback alc880_pcm_analog_playback +#define alc262_pcm_analog_capture alc880_pcm_analog_capture +#define alc262_pcm_digital_playback alc880_pcm_digital_playback +#define alc262_pcm_digital_capture alc880_pcm_digital_capture /* * BIOS auto configuration @@ -6672,35 +5866,26 @@ static void alc262_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc262_models[ALC262_MODEL_LAST] = { - [ALC262_BASIC] = "basic", - [ALC262_HIPPO] = "hippo", - [ALC262_HIPPO_1] = "hippo_1", - [ALC262_FUJITSU] = "fujitsu", - [ALC262_HP_BPC] = "hp-bpc", - [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", - [ALC262_BENQ_ED8] = "benq", - [ALC262_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc262_cfg_tbl[] = { - SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), - SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), - SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), - SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), - SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), - SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), - SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), - SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), - SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), - SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), - SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), - SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), - SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), +static struct hda_board_config alc262_cfg_tbl[] = { + { .modelname = "basic", .config = ALC262_BASIC }, + { .modelname = "fujitsu", .config = ALC262_FUJITSU }, + { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, + .config = ALC262_FUJITSU }, + { .modelname = "hp-bpc", .config = ALC262_HP_BPC }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x280c, + .config = ALC262_HP_BPC }, /* xw4400 */ + { .pci_subvendor = 0x103c, .pci_subdevice = 0x2801, + .config = ALC262_HP_BPC }, /* q965 */ + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, + .config = ALC262_HP_BPC }, /* xw6400 */ + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, + .config = ALC262_HP_BPC }, /* xw8400 */ + { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, + .config = ALC262_HP_BPC }, /* xw9400 */ + { .modelname = "benq", .config = ALC262_BENQ_ED8 }, + { .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560, + .config = ALC262_BENQ_ED8 }, + { .modelname = "auto", .config = ALC262_AUTO }, {} }; @@ -6715,30 +5900,6 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, }, - [ALC262_HIPPO] = { - .mixers = { alc262_base_mixer }, - .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, - }, - [ALC262_HIPPO_1] = { - .mixers = { alc262_hippo1_mixer }, - .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x02, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo1_unsol_event, - }, [ALC262_FUJITSU] = { .mixers = { alc262_fujitsu_mixer }, .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, @@ -6761,27 +5922,6 @@ static struct alc_config_preset alc262_presets[] = { .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 }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .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 }, - .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .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 }, @@ -6800,7 +5940,7 @@ static int patch_alc262(struct hda_codec *codec) int board_config; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -6816,11 +5956,9 @@ static int patch_alc262(struct hda_codec *codec) } #endif - board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, - alc262_models, - alc262_cfg_tbl); - - if (board_config < 0) { + board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); + + if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for ALC262, " "trying auto-probe from BIOS...\n"); board_config = ALC262_AUTO; @@ -6940,44 +6078,6 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { { 4, alc861_uniwill_m31_ch4_init }, }; -/* Set mic1 and line-in as input and unmute the mixer */ -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 */ - { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, -#if 0 - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ -#endif - { } /* end */ -}; -/* Set mic1 nad line-in as output and mute mixer */ -static struct hda_verb alc861_asus_ch6_init[] = { - /* set pin widget 1Ah (line in) for output (Back Surround)*/ - { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ - /* set pin widget 18h (mic1) for output (CLFE)*/ - { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ - { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, - - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, -#if 0 - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ -#endif - { } /* end */ -}; - -static struct hda_channel_mode alc861_asus_modes[2] = { - { 2, alc861_asus_ch2_init }, - { 6, alc861_asus_ch6_init }, -}; - /* patch-ALC861 */ static struct snd_kcontrol_new alc861_base_mixer[] = { @@ -7054,29 +6154,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { .private_value = ARRAY_SIZE(alc861_threestack_modes), }, { } /* end */ -}; - -static struct snd_kcontrol_new alc861_toshiba_mixer[] = { - /* output mixer control */ - HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), - - /*Capture mixer control */ - 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", - .count = 1, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, - - { } /* end */ -}; - +}; static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), @@ -7118,58 +6196,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { }, { } /* end */ }; - -static struct snd_kcontrol_new alc861_asus_mixer[] = { - /* output mixer control */ - HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), - - /* Input mixer control */ - HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), - 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?) */ - - /* Capture mixer control */ - 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", - .count = 1, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc_ch_mode_info, - .get = alc_ch_mode_get, - .put = alc_ch_mode_put, - .private_value = ARRAY_SIZE(alc861_asus_modes), - }, - { } -}; - -/* additional mixer */ -static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { - HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT), - { } -}; - + /* * generic initialization of ADC, input mixers and output mixers */ @@ -7190,7 +6217,7 @@ static struct hda_verb alc861_base_init_verbs[] = { /* port-E for HP out (front panel) */ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* route front PCM to HP */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, /* port-F for mic-in (front panel) with vref */ { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* port-G for CLFE (rear panel) */ @@ -7254,7 +6281,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { /* port-E for HP out (front panel) */ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* route front PCM to HP */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, /* port-F for mic-in (front panel) with vref */ { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* port-G for CLFE (rear panel) */ @@ -7314,7 +6341,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { /* port-E for HP out (front panel) */ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 /* route front PCM to HP */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, /* port-F for mic-in (front panel) with vref */ { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* port-G for CLFE (rear panel) */ @@ -7358,74 +6385,6 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { { } }; -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*/ - { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ - /* route front PCM to HP */ - { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, - /* port-B for mic-in (rear panel) with vref */ - { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - /* port-C for line-in (rear panel) */ - { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* port-D for Front */ - { 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 */ - /* route front PCM to HP */ - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, - /* port-F for mic-in (front panel) with vref */ - { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - /* port-G for CLFE (rear panel) */ - { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* port-H for side (rear panel) */ - { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* CD-in */ - { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* route front mic to ADC1*/ - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Unmute DAC0~3 & spdif out*/ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Unmute Mixer 14 (mic) 1c (Line in)*/ - {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - /* Unmute Stereo Mixer 15 */ - {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 */ - - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {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) */ - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - { } -}; - -/* additional init verbs for ASUS laptops */ -static struct hda_verb alc861_asus_laptop_init_verbs[] = { - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ - { } -}; - /* * generic initialization of ADC, input mixers and output mixers */ @@ -7478,39 +6437,6 @@ static struct hda_verb alc861_auto_init_verbs[] = { { } }; -static struct hda_verb alc861_toshiba_init_verbs[] = { - {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc861_toshiba_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x0f, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3, - 0x80, present ? 0 : 0x80); - snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3, - 0x80, present ? 0 : 0x80); -} - -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); -} - /* pcm configuration: identiacal with ALC880 */ #define alc861_pcm_analog_playback alc880_pcm_analog_playback #define alc861_pcm_analog_capture alc880_pcm_analog_capture @@ -7784,29 +6710,19 @@ static void alc861_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc861_models[ALC861_MODEL_LAST] = { - [ALC861_3ST] = "3stack", - [ALC660_3ST] = "3stack-660", - [ALC861_3ST_DIG] = "3stack-dig", - [ALC861_6ST_DIG] = "6stack-dig", - [ALC861_UNIWILL_M31] = "uniwill-m31", - [ALC861_TOSHIBA] = "toshiba", - [ALC861_ASUS] = "asus", - [ALC861_ASUS_LAPTOP] = "asus-laptop", - [ALC861_AUTO] = "auto", -}; - -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, 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(0x8086, 0xd600, "Intel", ALC861_3ST), +static struct hda_board_config alc861_cfg_tbl[] = { + { .modelname = "3stack", .config = ALC861_3ST }, + { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, + .config = ALC861_3ST }, + { .modelname = "3stack-660", .config = ALC660_3ST }, + { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, + .config = ALC660_3ST }, + { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, + { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, + { .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31}, + { .pci_subvendor = 0x1584, .pci_subdevice = 0x9072, + .config = ALC861_UNIWILL_M31 }, + { .modelname = "auto", .config = ALC861_AUTO }, {} }; @@ -7873,48 +6789,8 @@ static struct alc_config_preset alc861_presets[] = { .adc_nids = alc861_adc_nids, .input_mux = &alc861_capture_source, }, - [ALC861_TOSHIBA] = { - .mixers = { alc861_toshiba_mixer }, - .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), - .channel_mode = alc883_3ST_2ch_modes, - .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), - .adc_nids = alc861_adc_nids, - .input_mux = &alc861_capture_source, - .unsol_event = alc861_toshiba_unsol_event, - .init_hook = alc861_toshiba_automute, - }, - [ALC861_ASUS] = { - .mixers = { alc861_asus_mixer }, - .init_verbs = { alc861_asus_init_verbs }, - .num_dacs = ARRAY_SIZE(alc861_dac_nids), - .dac_nids = alc861_dac_nids, - .dig_out_nid = ALC861_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), - .channel_mode = alc861_asus_modes, - .need_dac_fix = 1, - .hp_nid = 0x06, - .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), - .adc_nids = alc861_adc_nids, - .input_mux = &alc861_capture_source, - }, - [ALC861_ASUS_LAPTOP] = { - .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, - .init_verbs = { alc861_asus_init_verbs, - alc861_asus_laptop_init_verbs }, - .num_dacs = ARRAY_SIZE(alc861_dac_nids), - .dac_nids = alc861_dac_nids, - .dig_out_nid = ALC861_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .need_dac_fix = 1, - .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), - .adc_nids = alc861_adc_nids, - .input_mux = &alc861_capture_source, - }, -}; + +}; static int patch_alc861(struct hda_codec *codec) @@ -7923,17 +6799,15 @@ static int patch_alc861(struct hda_codec *codec) int board_config; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; - board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, - alc861_models, - alc861_cfg_tbl); + board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); - if (board_config < 0) { + if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { printk(KERN_INFO "hda_codec: Unknown model for ALC861, " "trying auto-probe from BIOS...\n"); board_config = ALC861_AUTO; @@ -7971,707 +6845,20 @@ static int patch_alc861(struct hda_codec *codec) return 0; } -/* - * ALC861-VD support - * - * Based on ALC882 - * - * In addition, an independent DAC - */ -#define ALC861VD_DIGOUT_NID 0x06 - -static hda_nid_t alc861vd_dac_nids[4] = { - /* front, surr, clfe, side surr */ - 0x02, 0x03, 0x04, 0x05 -}; - -/* dac_nids for ALC660vd are in a different order - according to - * Realtek's driver. - * This should probably tesult in a different mixer for 6stack models - * of ALC660vd codecs, but for now there is only 3stack mixer - * - and it is the same as in 861vd. - * adc_nids in ALC660vd are (is) the same as in 861vd - */ -static hda_nid_t alc660vd_dac_nids[3] = { - /* front, rear, clfe, rear_surr */ - 0x02, 0x04, 0x03 -}; - -static hda_nid_t alc861vd_adc_nids[1] = { - /* ADC0 */ - 0x09, -}; - -/* input MUX */ -/* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc861vd_capture_source = { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Front Mic", 0x1 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - }, -}; - -#define alc861vd_mux_enum_info alc_mux_enum_info -#define alc861vd_mux_enum_get alc_mux_enum_get - -static int alc861vd_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[1] = { 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 alc861vd_3stack_2ch_modes[1] = { - { 2, NULL } -}; - -/* - * 6ch mode - */ -static struct hda_verb alc861vd_6stack_ch6_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, - { 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 */ -}; - -/* - * 8ch mode - */ -static struct hda_verb alc861vd_6stack_ch8_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 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 alc861vd_6stack_modes[2] = { - { 6, alc861vd_6stack_ch6_init }, - { 8, alc861vd_6stack_ch8_init }, -}; - -static struct snd_kcontrol_new alc861vd_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 snd_kcontrol_new alc861vd_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 = alc861vd_mux_enum_info, - .get = alc861vd_mux_enum_get, - .put = alc861vd_mux_enum_put, - }, - { } /* end */ -}; - -/* 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 alc861vd_6st_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - - HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 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", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - - HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - - 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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, 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("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 alc861vd_3st_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - - 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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, 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("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), - - { } /* end */ -}; - -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc861vd_volume_init_verbs[] = { - /* - * Unmute ADC0 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 - */ - /* 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)}, - - /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ - {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) - */ - /* 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}, - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* set up input amps for analog loopback */ - /* Amp Indices: DAC = 0, mixer = 1 */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - - { } -}; - -/* - * 3-stack pin configuration: - * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b - */ -static struct hda_verb alc861vd_3stack_init_verbs[] = { - /* - * Set pin mode and muting - */ - /* set front pin widgets 0x14 for output */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* 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}, - - { } -}; - -/* - * 6-stack pin configuration: - */ -static struct hda_verb alc861vd_6stack_init_verbs[] = { - /* - * Set pin mode and muting - */ - /* set front pin widgets 0x14 for output */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Rear Pin: output 1 (0x0d) */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* CLFE Pin: output 2 (0x0e) */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, - /* Side Pin: output 3 (0x0f) */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, - - /* 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}, - - { } -}; - -/* pcm configuration: identiacal with ALC880 */ -#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback -#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture -#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback -#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture - -/* - * configuration and preset - */ -static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { - [ALC660VD_3ST] = "3stack-660", - [ALC861VD_3ST] = "3stack", - [ALC861VD_3ST_DIG] = "3stack-digout", - [ALC861VD_6ST_DIG] = "6stack-digout", - [ALC861VD_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc861vd_cfg_tbl[] = { - 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), - {} -}; - -static struct alc_config_preset alc861vd_presets[] = { - [ALC660VD_3ST] = { - .mixers = { alc861vd_3st_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_3stack_init_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, - }, - [ALC861VD_3ST] = { - .mixers = { alc861vd_3st_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_3stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), - .dac_nids = alc861vd_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), - .channel_mode = alc861vd_3stack_2ch_modes, - .input_mux = &alc861vd_capture_source, - }, - [ALC861VD_3ST_DIG] = { - .mixers = { alc861vd_3st_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_3stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), - .dac_nids = alc861vd_dac_nids, - .dig_out_nid = ALC861VD_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), - .channel_mode = alc861vd_3stack_2ch_modes, - .input_mux = &alc861vd_capture_source, - }, - [ALC861VD_6ST_DIG] = { - .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_6stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), - .dac_nids = alc861vd_dac_nids, - .dig_out_nid = ALC861VD_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), - .channel_mode = alc861vd_6stack_modes, - .input_mux = &alc861vd_capture_source, - }, -}; - -/* - * BIOS auto configuration - */ -static void alc861vd_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); -} - -static void alc861vd_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]; - if (nid) - alc861vd_auto_set_output_and_unmute(codec, nid, - PIN_OUT, i); - } -} - - -static void alc861vd_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 and use dac 0 */ - alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); -} - -#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid) -#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID - -static void alc861vd_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 (alc861vd_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 != ALC861VD_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_MUTE); - } - } -} - -#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) -#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) - -/* add playback controls from the parsed DAC table */ -/* Based on ALC880 version. But ALC861VD has separate, - * different NIDs for mute/unmute switch and volume control */ -static int alc861vd_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", "CLFE", "Side"}; - hda_nid_t nid_v, nid_s; - int i, err; - - for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) - continue; - nid_v = alc861vd_idx_to_mixer_vol( - alc880_dac_to_idx( - spec->multiout.dac_nids[i])); - nid_s = alc861vd_idx_to_mixer_switch( - 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_v, 1, - 0, HDA_OUTPUT))) < 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) - 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) - 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) - 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) - 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) - return err; - } - } - return 0; -} - -/* add playback controls for speaker and HP outputs */ -/* Based on ALC880 version. But ALC861VD has separate, - * different NIDs for mute/unmute switch and volume control */ -static int alc861vd_auto_create_extra_out(struct alc_spec *spec, - hda_nid_t pin, const char *pfx) -{ - hda_nid_t nid_v, nid_s; - int err; - char name[32]; - - 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) - spec->multiout.hp_nid = nid_v; - else - spec->multiout.extra_out_nid[0] = nid_v; - /* control HP volume/switch on the output mixer amp */ - nid_v = alc861vd_idx_to_mixer_vol( - alc880_fixed_pin_idx(pin)); - nid_s = alc861vd_idx_to_mixer_switch( - 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) - 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) - 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) - return err; - } - return 0; -} - -/* 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 - * Based on ALC880 version - had to change it to override - * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ -static int alc861vd_parse_auto_config(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int err; - static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; - - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861vd_ignore)) < 0) - return err; - 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) - return err; - - spec->multiout.max_channels = spec->multiout.num_dacs * 2; - - if (spec->autocfg.dig_out_pin) - spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->init_verbs[spec->num_init_verbs++] - = alc861vd_volume_init_verbs; - - spec->num_mux_defs = 1; - spec->input_mux = &spec->private_imux; - - return 1; -} - -/* additional initialization for auto-configuration model */ -static void alc861vd_auto_init(struct hda_codec *codec) -{ - alc861vd_auto_init_multi_out(codec); - alc861vd_auto_init_hp_out(codec); - alc861vd_auto_init_analog_input(codec); -} - -static int patch_alc861vd(struct hda_codec *codec) -{ - struct alc_spec *spec; - int err, board_config; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, - alc861vd_models, - alc861vd_cfg_tbl); - - if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { - printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/" - "ALC861VD, trying auto-probe from BIOS...\n"); - board_config = ALC861VD_AUTO; - } - - if (board_config == ALC861VD_AUTO) { - /* automatic parse from the BIOS config */ - err = alc861vd_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 = ALC861VD_3ST; - } - } - - if (board_config != ALC861VD_AUTO) - setup_preset(spec, &alc861vd_presets[board_config]); - - spec->stream_name_analog = "ALC861VD Analog"; - spec->stream_analog_playback = &alc861vd_pcm_analog_playback; - spec->stream_analog_capture = &alc861vd_pcm_analog_capture; - - spec->stream_name_digital = "ALC861VD Digital"; - spec->stream_digital_playback = &alc861vd_pcm_digital_playback; - spec->stream_digital_capture = &alc861vd_pcm_digital_capture; - - spec->adc_nids = alc861vd_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); - - spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; - spec->num_mixers++; - - codec->patch_ops = alc_patch_ops; - - if (board_config == ALC861VD_AUTO) - spec->init_hook = alc861vd_auto_init; - - return 0; -} - /* * patch entries */ 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 }, - { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, - { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, - { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, - { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, + { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, + { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861", + .patch = patch_alc861 }, + { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", + .patch = patch_alc861 }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 6f4a39273b98..fe51ef3e49d2 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -37,37 +37,14 @@ #define NUM_CONTROL_ALLOC 32 #define STAC_HP_EVENT 0x37 -enum { - STAC_REF, - STAC_9200_MODELS -}; - -enum { - STAC_9205_REF, - STAC_9205_MODELS -}; - -enum { - STAC_925x_REF, - STAC_M2_2, - STAC_MA6, - STAC_925x_MODELS -}; - -enum { - STAC_D945_REF, - STAC_D945GTP3, - STAC_D945GTP5, - STAC_MACMINI, - STAC_922X_MODELS -}; - -enum { - STAC_D965_REF, - STAC_D965_3ST, - STAC_D965_5ST, - STAC_927X_MODELS -}; +#define STAC_REF 0 +#define STAC_D945GTP3 1 +#define STAC_D945GTP5 2 +#define STAC_MACMINI 3 +#define STAC_922X_MODELS 4 /* number of 922x models */ +#define STAC_D965_3ST 4 +#define STAC_D965_5ST 5 +#define STAC_927X_MODELS 6 /* number of 922x models */ struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; @@ -90,9 +67,6 @@ struct sigmatel_spec { unsigned int num_adcs; hda_nid_t *mux_nids; unsigned int num_muxes; - hda_nid_t *dmic_nids; - unsigned int num_dmics; - hda_nid_t dmux_nid; hda_nid_t dig_in_nid; /* pin widgets */ @@ -106,8 +80,6 @@ struct sigmatel_spec { struct snd_kcontrol_new *mixer; /* capture source */ - struct hda_input_mux *dinput_mux; - unsigned int cur_dmux; struct hda_input_mux *input_mux; unsigned int cur_mux[3]; @@ -120,7 +92,6 @@ struct sigmatel_spec { struct auto_pin_cfg autocfg; unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; - struct hda_input_mux private_dimux; struct hda_input_mux private_imux; }; @@ -136,18 +107,6 @@ static hda_nid_t stac9200_dac_nids[1] = { 0x02, }; -static hda_nid_t stac925x_adc_nids[1] = { - 0x03, -}; - -static hda_nid_t stac925x_mux_nids[1] = { - 0x0f, -}; - -static hda_nid_t stac925x_dac_nids[1] = { - 0x02, -}; - static hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; @@ -172,20 +131,11 @@ 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 stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, }; -static hda_nid_t stac925x_pin_nids[8] = { - 0x07, 0x08, 0x0a, 0x0b, - 0x0c, 0x0d, 0x10, 0x11, -}; - static hda_nid_t stac922x_pin_nids[10] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x15, 0x1b, @@ -204,34 +154,6 @@ static hda_nid_t stac9205_pin_nids[12] = { }; -static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - return snd_hda_input_mux_info(spec->dinput_mux, uinfo); -} - -static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - - ucontrol->value.enumerated.item[0] = spec->cur_dmux; - return 0; -} - -static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - - return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol, - spec->dmux_nid, &spec->cur_dmux); -} - static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -265,12 +187,6 @@ static struct hda_verb stac9200_core_init[] = { {} }; -static struct hda_verb stac925x_core_init[] = { - /* set dac0mux for dac converter */ - { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, - {} -}; - static struct hda_verb stac922x_core_init[] = { /* set master volume and direct control */ { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, @@ -316,23 +232,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new stac925x_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, - HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), - { } /* end */ -}; - /* This needs to be generated dynamically based on sequence */ static struct snd_kcontrol_new stac922x_mixer[] = { { @@ -364,7 +263,7 @@ static struct snd_kcontrol_new stac9227_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new stac927x_mixer[] = { +static snd_kcontrol_new_t stac927x_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -379,15 +278,7 @@ static struct snd_kcontrol_new stac927x_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new stac9205_mixer[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Digital Input Source", - .count = 1, - .info = stac92xx_dmux_enum_info, - .get = stac92xx_dmux_enum_get, - .put = stac92xx_dmux_enum_put, - }, +static snd_kcontrol_new_t stac9205_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -436,64 +327,22 @@ static unsigned int ref9200_pin_configs[8] = { 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { - [STAC_REF] = ref9200_pin_configs, -}; - -static const char *stac9200_models[STAC_9200_MODELS] = { - [STAC_REF] = "ref", +static unsigned int *stac9200_brd_tbl[] = { + ref9200_pin_configs, }; -static struct snd_pci_quirk stac9200_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, - "DFI LanParty", STAC_REF), +static struct hda_board_config stac9200_cfg_tbl[] = { + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* Dell laptops have BIOS problem */ - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5, - "Dell Inspiron 630m", STAC_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2, - "Dell Latitude D620", STAC_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb, - "Dell Latitude 120L", STAC_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc, - "Dell Latitude D820", STAC_REF), - {} /* terminator */ -}; - -static unsigned int ref925x_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e, -}; - -static unsigned int stac925x_MA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, -}; - -static unsigned int stac925xM2_2_pin_configs[8] = { - 0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020, - 0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e, -}; - -static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { - [STAC_REF] = ref925x_pin_configs, - [STAC_M2_2] = stac925xM2_2_pin_configs, - [STAC_MA6] = stac925x_MA6_pin_configs, -}; - -static const char *stac925x_models[STAC_925x_MODELS] = { - [STAC_REF] = "ref", - [STAC_M2_2] = "m2-2", - [STAC_MA6] = "m6", -}; - -static struct snd_pci_quirk stac925x_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), - SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2), + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, + .config = STAC_REF }, /* Dell Inspiron 630m */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, + .config = STAC_REF }, /* Dell Latitude D620 */ + { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, + .config = STAC_REF }, /* Dell Latitude 120L */ {} /* terminator */ }; @@ -516,80 +365,100 @@ static unsigned int d945gtp5_pin_configs[10] = { }; static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { - [STAC_D945_REF] = ref922x_pin_configs, + [STAC_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, [STAC_MACMINI] = d945gtp5_pin_configs, }; -static const char *stac922x_models[STAC_922X_MODELS] = { - [STAC_D945_REF] = "ref", - [STAC_D945GTP5] = "5stack", - [STAC_D945GTP3] = "3stack", - [STAC_MACMINI] = "macmini", -}; - -static struct snd_pci_quirk stac922x_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, - "DFI LanParty", STAC_D945_REF), - /* Intel 945G based systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048, - "Intel D945G", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110, - "Intel D945G", STAC_D945GTP3), - /* Intel D945G 5-stack systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404, - "Intel D945G", STAC_D945GTP5), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303, - "Intel D945G", STAC_D945GTP5), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013, - "Intel D945G", STAC_D945GTP5), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417, - "Intel D945G", STAC_D945GTP5), - /* Intel 945P based systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b, - "Intel D945P", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112, - "Intel D945P", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d, - "Intel D945P", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909, - "Intel D945P", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505, - "Intel D945P", STAC_D945GTP3), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, - "Intel D945P", STAC_D945GTP5), - /* other systems */ - /* Apple Mac Mini (early 2006) */ - SND_PCI_QUIRK(0x8384, 0x7680, - "Mac Mini", STAC_MACMINI), +static struct hda_board_config stac922x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D945GTP5 }, + { .modelname = "3stack", .config = STAC_D945GTP3 }, + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* SigmaTel reference board */ + /* Intel 945G based systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0101, + .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0202, + .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0606, + .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0601, + .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0111, + .config = STAC_D945GTP3 }, /* Intel D945GZP - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1115, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1116, + .config = STAC_D945GTP3 }, /* Intel D945GBO - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1117, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1118, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x1119, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x8826, + .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5049, + .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5055, + .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x5048, + .config = STAC_D945GTP3 }, /* Intel D945GPB - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0110, + .config = STAC_D945GTP3 }, /* Intel D945GLR - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0404, + .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0303, + .config = STAC_D945GTP5 }, /* Intel D945GNT - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0013, + .config = STAC_D945GTP5 }, /* Intel D955XBK - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0417, + .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ + /* Intel 945P based systems */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0b0b, + .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0112, + .config = STAC_D945GTP3 }, /* Intel D945PLN - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0d0d, + .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0909, + .config = STAC_D945GTP3 }, /* Intel D945PAW - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0505, + .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x0707, + .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */ + /* other systems */ + { .pci_subvendor = 0x8384, + .pci_subdevice = 0x7680, + .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */ {} /* terminator */ }; @@ -615,72 +484,120 @@ static unsigned int d965_5st_pin_configs[14] = { }; static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { - [STAC_D965_REF] = ref927x_pin_configs, + [STAC_REF] = ref927x_pin_configs, [STAC_D965_3ST] = d965_3st_pin_configs, [STAC_D965_5ST] = d965_5st_pin_configs, }; -static const char *stac927x_models[STAC_927X_MODELS] = { - [STAC_D965_REF] = "ref", - [STAC_D965_3ST] = "3stack", - [STAC_D965_5ST] = "5stack", -}; - -static struct snd_pci_quirk stac927x_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, - "DFI LanParty", STAC_D965_REF), +static struct hda_board_config stac927x_cfg_tbl[] = { + { .modelname = "5stack", .config = STAC_D965_5ST }, + { .modelname = "3stack", .config = STAC_D965_3ST }, + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* SigmaTel reference board */ /* Intel 946 based systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x3d01, + .config = STAC_D965_3ST }, /* D946 configuration */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0xa301, + .config = STAC_D965_3ST }, /* Intel D946GZT - 3 stack */ /* 965 based 3 stack systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2116, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2115, + .config = STAC_D965_3ST }, /* Intel DQ965WC - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2114, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2113, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2112, + .config = STAC_D965_3ST }, /* Intel DG965MS - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2111, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2110, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2009, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2008, + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2007, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2006, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2005, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2004, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2003, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2002, + .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2001, + .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */ /* 965 based 5 stack systems */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST), + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2301, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2302, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2303, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2304, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2305, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2501, + .config = STAC_D965_5ST }, /* Intel DG965MQ - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2502, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2503, + .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ + { .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2504, + .config = STAC_D965_5ST }, /* Intel DQ965GF - 5 Stack */ {} /* terminator */ }; static unsigned int ref9205_pin_configs[12] = { 0x40000100, 0x40000100, 0x01016011, 0x01014010, - 0x01813122, 0x01a19021, 0x40000100, 0x40000100, - 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 + 0x01813122, 0x01a19021, 0x40000100, 0x40000100, + 0x40000100, 0x40000100, 0x01441030, 0x01c41030 }; -static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { +static unsigned int *stac9205_brd_tbl[] = { ref9205_pin_configs, }; -static const char *stac9205_models[STAC_9205_MODELS] = { - [STAC_9205_REF] = "ref", -}; - -static struct snd_pci_quirk stac9205_cfg_tbl[] = { - /* SigmaTel reference board */ - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, - "DFI LanParty", STAC_9205_REF), +static struct hda_board_config stac9205_cfg_tbl[] = { + { .modelname = "ref", + .pci_subvendor = PCI_VENDOR_ID_INTEL, + .pci_subdevice = 0x2668, /* DFI LanParty */ + .config = STAC_REF }, /* SigmaTel reference board */ {} /* terminator */ }; @@ -1237,58 +1154,6 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, return 0; } -/* labels for dmic mux inputs */ -static const char *stac92xx_dmic_labels[5] = { - "Analog Inputs", "Digital Mic 1", "Digital Mic 2", - "Digital Mic 3", "Digital Mic 4" -}; - -/* create playback/capture controls for input pins on dmic capable codecs */ -static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, - const struct auto_pin_cfg *cfg) -{ - struct sigmatel_spec *spec = codec->spec; - struct hda_input_mux *dimux = &spec->private_dimux; - hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; - int i, j; - - dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; - dimux->items[dimux->num_items].index = 0; - dimux->num_items++; - - for (i = 0; i < spec->num_dmics; i++) { - int index; - int num_cons; - unsigned int def_conf; - - def_conf = snd_hda_codec_read(codec, - spec->dmic_nids[i], - 0, - AC_VERB_GET_CONFIG_DEFAULT, - 0); - if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) - continue; - - num_cons = snd_hda_get_connections(codec, - spec->dmux_nid, - con_lst, - HDA_MAX_NUM_INPUTS); - for (j = 0; j < num_cons; j++) - if (con_lst[j] == spec->dmic_nids[i]) { - index = j; - goto found; - } - continue; -found: - dimux->items[dimux->num_items].label = - stac92xx_dmic_labels[dimux->num_items]; - dimux->items[dimux->num_items].index = index; - dimux->num_items++; - } - - return 0; -} - /* create playback/capture controls for input pins */ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { @@ -1373,9 +1238,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out struct sigmatel_spec *spec = codec->spec; int err; - if ((err = snd_hda_parse_pin_def_config(codec, - &spec->autocfg, - spec->dmic_nids)) < 0) + if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) return err; if (! spec->autocfg.line_outs) return 0; /* can't find valid pin config */ @@ -1391,11 +1254,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) return err; - if (spec->num_dmics > 0) - if ((err = stac92xx_auto_create_dmic_input_ctls(codec, - &spec->autocfg)) < 0) - return err; - spec->multiout.max_channels = spec->multiout.num_dacs * 2; if (spec->multiout.max_channels > 2) spec->surr_switch = 1; @@ -1409,7 +1267,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out spec->mixers[spec->num_mixers++] = spec->kctl_alloc; spec->input_mux = &spec->private_imux; - spec->dinput_mux = &spec->private_dimux; return 1; } @@ -1509,7 +1366,6 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; spec->input_mux = &spec->private_imux; - spec->dinput_mux = &spec->private_dimux; return 1; } @@ -1592,11 +1448,6 @@ static int stac92xx_init(struct hda_codec *codec) stac92xx_auto_set_pinctl(codec, nid, pinctl); } } - if (spec->num_dmics > 0) - for (i = 0; i < spec->num_dmics; i++) - stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], - AC_PINCTL_IN_EN); - if (cfg->dig_out_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, AC_PINCTL_OUT_EN); @@ -1747,9 +1598,7 @@ static int patch_stac9200(struct hda_codec *codec) codec->spec = spec; spec->num_pins = 8; spec->pin_nids = stac9200_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, - stac9200_models, - stac9200_cfg_tbl); + spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); err = stac92xx_save_bios_config_regs(codec); @@ -1769,7 +1618,6 @@ static int patch_stac9200(struct hda_codec *codec) spec->adc_nids = stac9200_adc_nids; spec->mux_nids = stac9200_mux_nids; spec->num_muxes = 1; - spec->num_dmics = 0; spec->init = stac9200_core_init; spec->mixer = stac9200_mixer; @@ -1785,56 +1633,6 @@ static int patch_stac9200(struct hda_codec *codec) return 0; } -static int patch_stac925x(struct hda_codec *codec) -{ - struct sigmatel_spec *spec; - int err; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - spec->num_pins = 8; - spec->pin_nids = stac925x_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, - stac925x_models, - stac925x_cfg_tbl); - if (spec->board_config < 0) { - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n"); - err = stac92xx_save_bios_config_regs(codec); - if (err < 0) { - stac92xx_free(codec); - return err; - } - spec->pin_configs = spec->bios_pin_configs; - } else if (stac925x_brd_tbl[spec->board_config] != NULL){ - spec->pin_configs = stac925x_brd_tbl[spec->board_config]; - stac92xx_set_config_regs(codec); - } - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = stac925x_dac_nids; - spec->adc_nids = stac925x_adc_nids; - spec->mux_nids = stac925x_mux_nids; - spec->num_muxes = 1; - spec->num_dmics = 0; - - spec->init = stac925x_core_init; - spec->mixer = stac925x_mixer; - - err = stac92xx_parse_auto_config(codec, 0x8, 0x7); - if (err < 0) { - stac92xx_free(codec); - return err; - } - - codec->patch_ops = stac92xx_patch_ops; - - return 0; -} - static int patch_stac922x(struct hda_codec *codec) { struct sigmatel_spec *spec; @@ -1847,9 +1645,7 @@ static int patch_stac922x(struct hda_codec *codec) codec->spec = spec; spec->num_pins = 10; spec->pin_nids = stac922x_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, - stac922x_models, - stac922x_cfg_tbl); + spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " "using BIOS defaults\n"); @@ -1867,7 +1663,6 @@ 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_dmics = 0; spec->init = stac922x_core_init; spec->mixer = stac922x_mixer; @@ -1900,9 +1695,7 @@ static int patch_stac927x(struct hda_codec *codec) codec->spec = spec; spec->num_pins = 14; spec->pin_nids = stac927x_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, - stac927x_models, - stac927x_cfg_tbl); + spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); err = stac92xx_save_bios_config_regs(codec); @@ -1921,7 +1714,6 @@ static int patch_stac927x(struct hda_codec *codec) spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = 3; - spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; @@ -1929,7 +1721,6 @@ static int patch_stac927x(struct hda_codec *codec) spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = 3; - spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; break; @@ -1937,7 +1728,6 @@ static int patch_stac927x(struct hda_codec *codec) spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; spec->num_muxes = 3; - spec->num_dmics = 0; spec->init = stac927x_core_init; spec->mixer = stac927x_mixer; } @@ -1967,9 +1757,7 @@ static int patch_stac9205(struct hda_codec *codec) codec->spec = spec; spec->num_pins = 14; spec->pin_nids = stac9205_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, - stac9205_models, - stac9205_cfg_tbl); + spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); if (spec->board_config < 0) { snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); err = stac92xx_save_bios_config_regs(codec); @@ -1985,28 +1773,13 @@ 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->dmic_nids = stac9205_dmic_nids; - spec->num_dmics = 2; - spec->dmux_nid = 0x1d; + spec->num_muxes = 3; spec->init = stac9205_core_init; spec->mixer = stac9205_mixer; spec->multiout.dac_nids = spec->dac_nids; - /* Configure GPIO0 as EAPD output */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, 0x00000001); - /* Configure GPIO0 as CMOS */ - snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); - /* Assert GPIO0 high */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, 0x00000001); - /* Enable GPIO0 */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, 0x00000001); - err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); if (err < 0) { stac92xx_free(codec); @@ -2190,19 +1963,18 @@ enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ /* Unknown. id=0x83847661 and subsys=0x104D1200. */ STAC9872K_VAIO, /* AR Series. id=0x83847664 and subsys=104D1300 */ - CXD9872AKD_VAIO, - STAC_9872_MODELS, -}; - -static const char *stac9872_models[STAC_9872_MODELS] = { - [CXD9872RD_VAIO] = "vaio", - [CXD9872AKD_VAIO] = "vaio-ar", -}; - -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), + CXD9872AKD_VAIO + }; + +static struct hda_board_config stac9872_cfg_tbl[] = { + { .modelname = "vaio", .config = CXD9872RD_VAIO }, + { .modelname = "vaio-ar", .config = CXD9872AKD_VAIO }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, + .config = CXD9872RD_VAIO }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, + .config = CXD9872RD_VAIO }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, + .config = CXD9872AKD_VAIO }, {} }; @@ -2211,9 +1983,7 @@ static int patch_stac9872(struct hda_codec *codec) struct sigmatel_spec *spec; int board_config; - board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, - stac9872_models, - stac9872_cfg_tbl); + board_config = snd_hda_check_board_config(codec, stac9872_cfg_tbl); if (board_config < 0) /* unknown config, let generic-parser do its job... */ return snd_hda_parse_generic_codec(codec); @@ -2285,12 +2055,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, - { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x }, - { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x }, - { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x }, - { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, - { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, - { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, /* The following does not take into account .id=0x83847661 when subsys = * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are * currently not fully supported. diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c deleted file mode 100644 index 4c839b031729..000000000000 --- a/trunk/sound/pci/hda/patch_via.c +++ /dev/null @@ -1,1396 +0,0 @@ -/* - * Universal Interface for Intel High Definition Audio Codec - * - * HD audio interface patch for VIA VT1708 codec - * - * Copyright (c) 2006 Lydia Wang - * Takashi Iwai - * - * This driver 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 driver 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 - */ - -/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */ -/* */ -/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */ -/* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */ -/* 2006-08-02 Lydia Wang Add support to VT1709 codec */ -/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ -/* */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -#include -#include -#include -#include -#include -#include -#include "hda_codec.h" -#include "hda_local.h" - - -/* amp values */ -#define AMP_VAL_IDX_SHIFT 19 -#define AMP_VAL_IDX_MASK (0x0f<<19) - -#define NUM_CONTROL_ALLOC 32 -#define NUM_VERB_ALLOC 32 - -/* Pin Widget NID */ -#define VT1708_HP_NID 0x13 -#define VT1708_DIGOUT_NID 0x14 -#define VT1708_DIGIN_NID 0x16 - -#define VT1709_HP_DAC_NID 0x28 -#define VT1709_DIGOUT_NID 0x13 -#define VT1709_DIGIN_NID 0x17 - -#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b) -#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713) -#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717) - - -enum { - VIA_CTL_WIDGET_VOL, - VIA_CTL_WIDGET_MUTE, -}; - -enum { - AUTO_SEQ_FRONT, - AUTO_SEQ_SURROUND, - AUTO_SEQ_CENLFE, - AUTO_SEQ_SIDE -}; - -static struct snd_kcontrol_new vt1708_control_templates[] = { - HDA_CODEC_VOLUME(NULL, 0, 0, 0), - HDA_CODEC_MUTE(NULL, 0, 0, 0), -}; - - -struct via_spec { - /* codec parameterization */ - struct snd_kcontrol_new *mixers[3]; - unsigned int num_mixers; - - struct hda_verb *init_verbs; - - char *stream_name_analog; - struct hda_pcm_stream *stream_analog_playback; - struct hda_pcm_stream *stream_analog_capture; - - char *stream_name_digital; - struct hda_pcm_stream *stream_digital_playback; - struct hda_pcm_stream *stream_digital_capture; - - /* playback */ - struct hda_multi_out multiout; - - /* capture */ - unsigned int num_adc_nids; - hda_nid_t *adc_nids; - hda_nid_t dig_in_nid; - - /* capture source */ - const struct hda_input_mux *input_mux; - unsigned int cur_mux[3]; - - /* PCM information */ - struct hda_pcm pcm_rec[2]; - - /* dynamic controls, init_verbs and input_mux */ - struct auto_pin_cfg autocfg; - unsigned int num_kctl_alloc, num_kctl_used; - struct snd_kcontrol_new *kctl_alloc; - struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; -}; - -static hda_nid_t vt1708_adc_nids[2] = { - /* ADC1-2 */ - 0x15, 0x27 -}; - -static hda_nid_t vt1709_adc_nids[3] = { - /* ADC1-2 */ - 0x14, 0x15, 0x16 -}; - -/* add dynamic controls */ -static int via_add_control(struct via_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; - - /* 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); - kfree(spec->kctl_alloc); - } - spec->kctl_alloc = knew; - spec->num_kctl_alloc = num; - } - - knew = &spec->kctl_alloc[spec->num_kctl_used]; - *knew = vt1708_control_templates[type]; - knew->name = kstrdup(name, GFP_KERNEL); - - if (!knew->name) - return -ENOMEM; - knew->private_value = val; - spec->num_kctl_used++; - return 0; -} - -/* create input playback/capture controls for the given pin */ -static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, - const char *ctlname, int idx, int mix_nid) -{ - char name[32]; - int err; - - sprintf(name, "%s Playback Volume", ctlname); - err = via_add_control(spec, VIA_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); - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); - if (err < 0) - return err; - return 0; -} - -static void via_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); -} - - -static void via_auto_init_multi_out(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int i; - - for (i = 0; i <= AUTO_SEQ_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; - if (nid) - via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); - } -} - -static void via_auto_init_hp_out(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - hda_nid_t pin; - - pin = spec->autocfg.hp_pins[0]; - if (pin) /* connect to front */ - via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); -} - -static void via_auto_init_analog_input(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int i; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - hda_nid_t nid = spec->autocfg.input_pins[i]; - - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - (i <= AUTO_PIN_FRONT_MIC ? - PIN_VREF50 : PIN_IN)); - - } -} -/* - * input MUX handling - */ -static int via_mux_enum_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct via_spec *spec = codec->spec; - return snd_hda_input_mux_info(spec->input_mux, uinfo); -} - -static int via_mux_enum_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct via_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; - return 0; -} - -static int via_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct via_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - unsigned int vendor_id = codec->vendor_id; - - /* AIW0 lydia 060801 add for correct sw0 input select */ - if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - 0x18, &spec->cur_mux[adc_idx]); - else if ((IS_VT1709_10CH_VENDORID(vendor_id) || - IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0) ) - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - 0x19, &spec->cur_mux[adc_idx]); - else - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - spec->adc_nids[adc_idx], - &spec->cur_mux[adc_idx]); -} - -/* capture mixer elements */ -static struct snd_kcontrol_new vt1708_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 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 = via_mux_enum_info, - .get = via_mux_enum_get, - .put = via_mux_enum_put, - }, - { } /* end */ -}; -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb vt1708_volume_init_verbs[] = { - /* - * Unmute ADC0-1 and set the default input to mic-in - */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x27, 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 - */ - /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - - /* - * Set up output mixers (0x19 - 0x1b) - */ - /* set vol=0 to output mixers */ - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Setup default input to PW4 */ - {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Set mic as default input of sw0 */ - {0x18, AC_VERB_SET_CONNECT_SEL, 0x2}, - /* PW9 Output enable */ - {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, -}; - -static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct via_spec *spec = codec->spec; - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); -} - -static int via_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_analog_prepare(codec, &spec->multiout, - stream_tag, format, substream); -} - -static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct via_spec *spec = codec->spec; - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); -} - -/* - * Digital out - */ -static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct via_spec *spec = codec->spec; - return snd_hda_multi_out_dig_open(codec, &spec->multiout); -} - -static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct via_spec *spec = codec->spec; - return snd_hda_multi_out_dig_close(codec, &spec->multiout); -} - -/* - * Analog capture - */ -static int via_capture_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; - - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - stream_tag, 0, format); - return 0; -} - -static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - struct via_spec *spec = codec->spec; - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - 0, 0, 0); - return 0; -} - -static struct hda_pcm_stream vt1708_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 8, - .nid = 0x10, /* NID to query formats and rates */ - .ops = { - .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream vt1708_pcm_analog_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0x15, /* NID to query formats and rates */ - .ops = { - .prepare = via_capture_pcm_prepare, - .cleanup = via_capture_pcm_cleanup - }, -}; - -static struct hda_pcm_stream vt1708_pcm_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - /* NID is set in via_build_pcms */ - .ops = { - .open = via_dig_playback_pcm_open, - .close = via_dig_playback_pcm_close - }, -}; - -static struct hda_pcm_stream vt1708_pcm_digital_capture = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, -}; - -static int via_build_controls(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int err; - int i; - - for (i = 0; i < spec->num_mixers; i++) { - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); - if (err < 0) - return err; - } - - if (spec->multiout.dig_out_nid) { - err = snd_hda_create_spdif_out_ctls(codec, - spec->multiout.dig_out_nid); - if (err < 0) - return err; - } - if (spec->dig_in_nid) { - err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); - if (err < 0) - return err; - } - return 0; -} - -static int via_build_pcms(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - struct hda_pcm *info = spec->pcm_rec; - - codec->num_pcms = 1; - codec->pcm_info = info; - - info->name = spec->stream_name_analog; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; - - info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = - spec->multiout.max_channels; - - if (spec->multiout.dig_out_nid || spec->dig_in_nid) { - codec->num_pcms++; - info++; - info->name = spec->stream_name_digital; - if (spec->multiout.dig_out_nid) { - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = - *(spec->stream_digital_playback); - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = - spec->multiout.dig_out_nid; - } - if (spec->dig_in_nid) { - info->stream[SNDRV_PCM_STREAM_CAPTURE] = - *(spec->stream_digital_capture); - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = - spec->dig_in_nid; - } - } - - return 0; -} - -static void via_free(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - unsigned int i; - - if (!spec) - return; - - if (spec->kctl_alloc) { - for (i = 0; i < spec->num_kctl_used; i++) - kfree(spec->kctl_alloc[i].name); - kfree(spec->kctl_alloc); - } - - kfree(codec->spec); -} - -static int via_init(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - snd_hda_sequence_write(codec, spec->init_verbs); - return 0; -} - -#ifdef CONFIG_PM -/* - * resume - */ -static int via_resume(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int i; - - via_init(codec); - for (i = 0; i < spec->num_mixers; i++) - snd_hda_resume_ctls(codec, spec->mixers[i]); - if (spec->multiout.dig_out_nid) - snd_hda_resume_spdif_out(codec); - if (spec->dig_in_nid) - snd_hda_resume_spdif_in(codec); - - return 0; -} -#endif - -/* - */ -static struct hda_codec_ops via_patch_ops = { - .build_controls = via_build_controls, - .build_pcms = via_build_pcms, - .init = via_init, - .free = via_free, -#ifdef CONFIG_PM - .resume = via_resume, -#endif -}; - -/* fill in the dac_nids table from the parsed pin configuration */ -static int vt1708_auto_fill_dac_nids(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - int i; - hda_nid_t nid; - - spec->multiout.num_dacs = cfg->line_outs; - - spec->multiout.dac_nids = spec->private_dac_nids; - - for(i = 0; i < 4; i++) { - nid = cfg->line_out_pins[i]; - if (nid) { - /* config dac list */ - switch (i) { - case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x10; - break; - case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x12; - break; - case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x13; - break; - case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x11; - break; - } - } - } - - return 0; -} - -/* add playback controls from the parsed DAC table */ -static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; - hda_nid_t nid, nid_vol = 0; - int i, err; - - for (i = 0; i <= AUTO_SEQ_SIDE; i++) { - nid = cfg->line_out_pins[i]; - - if (!nid) - continue; - - if (i != AUTO_SEQ_FRONT) - nid_vol = 0x1b - i + 1; - - if (i == AUTO_SEQ_CENLFE) { - /* Center/LFE */ - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } else if (i == AUTO_SEQ_FRONT){ - /* add control to mixer index 0 */ - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Master Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Master Front Playback Switch", - HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - - /* add control to PW3 */ - sprintf(name, "%s Playback Volume", chname[i]); - err = via_add_control(spec, VIA_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 = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } else { - sprintf(name, "%s Playback Volume", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - sprintf(name, "%s Playback Switch", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } - } - - return 0; -} - -static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) -{ - int err; - - if (!pin) - return 0; - - spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ - - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Headphone Playback Switch", - 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 vt1708_auto_create_analog_input_ctls(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - static char *labels[] = { - "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL - }; - struct hda_input_mux *imux = &spec->private_imux; - int i, err, idx = 0; - - /* for internal loopback recording select */ - imux->items[imux->num_items].label = "Stereo Mixer"; - imux->items[imux->num_items].index = idx; - imux->num_items++; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - if (!cfg->input_pins[i]) - continue; - - switch (cfg->input_pins[i]) { - case 0x1d: /* Mic */ - idx = 2; - break; - - case 0x1e: /* Line In */ - idx = 3; - break; - - case 0x21: /* Front Mic */ - idx = 4; - break; - - case 0x24: /* CD */ - idx = 1; - break; - } - err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], - idx, 0x17); - if (err < 0) - return err; - imux->items[imux->num_items].label = labels[i]; - imux->items[imux->num_items].index = idx; - imux->num_items++; - } - return 0; -} - -static int vt1708_parse_auto_config(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int err; - - err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); - if (err < 0) - return err; - err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg); - if (err < 0) - return err; - if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) - return 0; /* can't find valid BIOS pin config */ - - err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); - if (err < 0) - return err; - err = vt1708_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 = VT1708_DIGOUT_NID; - if (spec->autocfg.dig_in_pin) - spec->dig_in_nid = VT1708_DIGIN_NID; - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->init_verbs = vt1708_volume_init_verbs; - - spec->input_mux = &spec->private_imux; - - return 1; -} - -/* init callback for auto-configuration model -- overriding the default init */ -static int via_auto_init(struct hda_codec *codec) -{ - via_init(codec); - via_auto_init_multi_out(codec); - via_auto_init_hp_out(codec); - via_auto_init_analog_input(codec); - return 0; -} - -static int patch_vt1708(struct hda_codec *codec) -{ - struct via_spec *spec; - int err; - - /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - /* automatic parse from the BIOS config */ - err = vt1708_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } else if (!err) { - printk(KERN_INFO "hda_codec: Cannot set up configuration " - "from BIOS. Using genenic mode...\n"); - } - - - spec->stream_name_analog = "VT1708 Analog"; - spec->stream_analog_playback = &vt1708_pcm_analog_playback; - spec->stream_analog_capture = &vt1708_pcm_analog_capture; - - spec->stream_name_digital = "VT1708 Digital"; - spec->stream_digital_playback = &vt1708_pcm_digital_playback; - spec->stream_digital_capture = &vt1708_pcm_digital_capture; - - - if (!spec->adc_nids && spec->input_mux) { - spec->adc_nids = vt1708_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); - spec->mixers[spec->num_mixers] = vt1708_capture_mixer; - spec->num_mixers++; - } - - codec->patch_ops = via_patch_ops; - - codec->patch_ops.init = via_auto_init; - - return 0; -} - -/* capture mixer elements */ -static struct snd_kcontrol_new vt1709_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 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 = via_mux_enum_info, - .get = via_mux_enum_get, - .put = via_mux_enum_put, - }, - { } /* end */ -}; - -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb vt1709_10ch_volume_init_verbs[] = { - /* - * Unmute ADC0-2 and set the default input to mic-in - */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x16, 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 - */ - /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - - /* - * Set up output selector (0x1a, 0x1b, 0x29) - */ - /* set vol=0 to output mixers */ - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* - * Unmute PW3 and PW4 - */ - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Set input of PW4 as AOW4 */ - {0x20, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Set mic as default input of sw0 */ - {0x19, AC_VERB_SET_CONNECT_SEL, 0x2}, - /* PW9 Output enable */ - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - { } -}; - -static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 10, - .nid = 0x10, /* NID to query formats and rates */ - .ops = { - .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 6, - .nid = 0x10, /* NID to query formats and rates */ - .ops = { - .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream vt1709_pcm_analog_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0x14, /* NID to query formats and rates */ - .ops = { - .prepare = via_capture_pcm_prepare, - .cleanup = via_capture_pcm_cleanup - }, -}; - -static struct hda_pcm_stream vt1709_pcm_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - /* NID is set in via_build_pcms */ - .ops = { - .open = via_dig_playback_pcm_open, - .close = via_dig_playback_pcm_close - }, -}; - -static struct hda_pcm_stream vt1709_pcm_digital_capture = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, -}; - -static int vt1709_auto_fill_dac_nids(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - int i; - hda_nid_t nid; - - if (cfg->line_outs == 4) /* 10 channels */ - spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */ - else if (cfg->line_outs == 3) /* 6 channels */ - spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */ - - spec->multiout.dac_nids = spec->private_dac_nids; - - if (cfg->line_outs == 4) { /* 10 channels */ - for (i = 0; i < cfg->line_outs; i++) { - nid = cfg->line_out_pins[i]; - if (nid) { - /* config dac list */ - switch (i) { - case AUTO_SEQ_FRONT: - /* AOW0 */ - spec->multiout.dac_nids[i] = 0x10; - break; - case AUTO_SEQ_CENLFE: - /* AOW2 */ - spec->multiout.dac_nids[i] = 0x12; - break; - case AUTO_SEQ_SURROUND: - /* AOW3 */ - spec->multiout.dac_nids[i] = 0x27; - break; - case AUTO_SEQ_SIDE: - /* AOW1 */ - spec->multiout.dac_nids[i] = 0x11; - break; - default: - break; - } - } - } - spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ - - } else if (cfg->line_outs == 3) { /* 6 channels */ - for(i = 0; i < cfg->line_outs; i++) { - nid = cfg->line_out_pins[i]; - if (nid) { - /* config dac list */ - switch(i) { - case AUTO_SEQ_FRONT: - /* AOW0 */ - spec->multiout.dac_nids[i] = 0x10; - break; - case AUTO_SEQ_CENLFE: - /* AOW2 */ - spec->multiout.dac_nids[i] = 0x12; - break; - case AUTO_SEQ_SURROUND: - /* AOW1 */ - spec->multiout.dac_nids[i] = 0x11; - break; - default: - break; - } - } - } - } - - return 0; -} - -/* add playback controls from the parsed DAC table */ -static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - char name[32]; - static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; - hda_nid_t nid = 0; - int i, err; - - for (i = 0; i <= AUTO_SEQ_SIDE; i++) { - nid = cfg->line_out_pins[i]; - - if (!nid) - continue; - - if (i == AUTO_SEQ_CENLFE) { - /* Center/LFE */ - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } else if (i == AUTO_SEQ_FRONT){ - /* add control to mixer index 0 */ - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Master Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Master Front Playback Switch", - HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - - /* add control to PW3 */ - sprintf(name, "%s Playback Volume", chname[i]); - err = via_add_control(spec, VIA_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 = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } else if (i == AUTO_SEQ_SURROUND) { - sprintf(name, "%s Playback Volume", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - sprintf(name, "%s Playback Switch", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } else if (i == AUTO_SEQ_SIDE) { - sprintf(name, "%s Playback Volume", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - sprintf(name, "%s Playback Switch", chname[i]); - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - } - } - - return 0; -} - -static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) -{ - int err; - - if (!pin) - return 0; - - if (spec->multiout.num_dacs == 5) /* 10 channels */ - spec->multiout.hp_nid = VT1709_HP_DAC_NID; - else if (spec->multiout.num_dacs == 3) /* 6 channels */ - spec->multiout.hp_nid = 0; - - err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); - if (err < 0) - return err; - err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, - "Headphone Playback Switch", - 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 vt1709_auto_create_analog_input_ctls(struct via_spec *spec, - const struct auto_pin_cfg *cfg) -{ - static char *labels[] = { - "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL - }; - struct hda_input_mux *imux = &spec->private_imux; - int i, err, idx = 0; - - /* for internal loopback recording select */ - imux->items[imux->num_items].label = "Stereo Mixer"; - imux->items[imux->num_items].index = idx; - imux->num_items++; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - if (!cfg->input_pins[i]) - continue; - - switch (cfg->input_pins[i]) { - case 0x1d: /* Mic */ - idx = 2; - break; - - case 0x1e: /* Line In */ - idx = 3; - break; - - case 0x21: /* Front Mic */ - idx = 4; - break; - - case 0x23: /* CD */ - idx = 1; - break; - } - err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], - idx, 0x18); - if (err < 0) - return err; - imux->items[imux->num_items].label = labels[i]; - imux->items[imux->num_items].index = idx; - imux->num_items++; - } - return 0; -} - -static int vt1709_parse_auto_config(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int err; - - err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); - if (err < 0) - return err; - err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg); - if (err < 0) - return err; - if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) - return 0; /* can't find valid BIOS pin config */ - - err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); - if (err < 0) - return err; - err = vt1709_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 = VT1709_DIGOUT_NID; - if (spec->autocfg.dig_in_pin) - spec->dig_in_nid = VT1709_DIGIN_NID; - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->input_mux = &spec->private_imux; - - return 1; -} - -static int patch_vt1709_10ch(struct hda_codec *codec) -{ - struct via_spec *spec; - int err; - - /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - err = vt1709_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } else if (!err) { - printk(KERN_INFO "hda_codec: Cannot set up configuration. " - "Using genenic mode...\n"); - } - - spec->init_verbs = vt1709_10ch_volume_init_verbs; - - spec->stream_name_analog = "VT1709 Analog"; - spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; - spec->stream_analog_capture = &vt1709_pcm_analog_capture; - - spec->stream_name_digital = "VT1709 Digital"; - spec->stream_digital_playback = &vt1709_pcm_digital_playback; - spec->stream_digital_capture = &vt1709_pcm_digital_capture; - - - if (!spec->adc_nids && spec->input_mux) { - spec->adc_nids = vt1709_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); - spec->mixers[spec->num_mixers] = vt1709_capture_mixer; - spec->num_mixers++; - } - - codec->patch_ops = via_patch_ops; - - codec->patch_ops.init = via_auto_init; - - return 0; -} -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb vt1709_6ch_volume_init_verbs[] = { - /* - * Unmute ADC0-2 and set the default input to mic-in - */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x16, 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 - */ - /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - - /* - * Set up output selector (0x1a, 0x1b, 0x29) - */ - /* set vol=0 to output mixers */ - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* - * Unmute PW3 and PW4 - */ - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - - /* Set input of PW4 as MW0 */ - {0x20, AC_VERB_SET_CONNECT_SEL, 0}, - /* Set mic as default input of sw0 */ - {0x19, AC_VERB_SET_CONNECT_SEL, 0x2}, - /* PW9 Output enable */ - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - { } -}; - -static int patch_vt1709_6ch(struct hda_codec *codec) -{ - struct via_spec *spec; - int err; - - /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - err = vt1709_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } else if (!err) { - printk(KERN_INFO "hda_codec: Cannot set up configuration. " - "Using genenic mode...\n"); - } - - spec->init_verbs = vt1709_6ch_volume_init_verbs; - - spec->stream_name_analog = "VT1709 Analog"; - spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; - spec->stream_analog_capture = &vt1709_pcm_analog_capture; - - spec->stream_name_digital = "VT1709 Digital"; - spec->stream_digital_playback = &vt1709_pcm_digital_playback; - spec->stream_digital_capture = &vt1709_pcm_digital_capture; - - - if (!spec->adc_nids && spec->input_mux) { - spec->adc_nids = vt1709_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); - spec->mixers[spec->num_mixers] = vt1709_capture_mixer; - spec->num_mixers++; - } - - codec->patch_ops = via_patch_ops; - - codec->patch_ops.init = via_auto_init; - - return 0; -} - -/* - * patch entries - */ -struct hda_codec_preset snd_hda_preset_via[] = { - { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, - { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, - { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, - { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, - { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, - { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, - { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, - { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch}, - { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, - { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, - { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, - { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch}, - {} /* terminator */ -}; diff --git a/trunk/sound/pci/ice1712/Makefile b/trunk/sound/pci/ice1712/Makefile index 6efdd62f6837..7837cef8855c 100644 --- a/trunk/sound/pci/ice1712/Makefile +++ b/trunk/sound/pci/ice1712/Makefile @@ -5,7 +5,7 @@ snd-ice17xx-ak4xxx-objs := ak4xxx.o snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o -snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o wtm.o +snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o # Toplevel Module Dependency obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o diff --git a/trunk/sound/pci/ice1712/amp.c b/trunk/sound/pci/ice1712/amp.c index 6e22d326df32..59c4078ad331 100644 --- a/trunk/sound/pci/ice1712/amp.c +++ b/trunk/sound/pci/ice1712/amp.c @@ -42,7 +42,7 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) { - static const unsigned short wm_inits[] = { + static unsigned short wm_inits[] = { WM_ATTEN_L, 0x0000, /* 0 db */ WM_ATTEN_R, 0x0000, /* 0 db */ WM_DAC_CTRL, 0x0008, /* 24bit I2S */ @@ -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", diff --git a/trunk/sound/pci/ice1712/amp.h b/trunk/sound/pci/ice1712/amp.h index 7b667bad0c6b..a0fc89b48122 100644 --- a/trunk/sound/pci/ice1712/amp.h +++ b/trunk/sound/pci/ice1712/amp.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/aureon.c b/trunk/sound/pci/ice1712/aureon.c index 6941d85dfec9..9e76cebd2d22 100644 --- a/trunk/sound/pci/ice1712/aureon.c +++ b/trunk/sound/pci/ice1712/aureon.c @@ -294,7 +294,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r static int aureon_ac97_init (struct snd_ice1712 *ice) { int i; - static const unsigned short ac97_defaults[] = { + static unsigned short ac97_defaults[] = { 0x00, 0x9640, 0x02, 0x8000, 0x04, 0x8000, @@ -474,8 +474,7 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned tmp = snd_ice1712_gpio_read(ice); - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) { + if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) { snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); mosi = PRODIGY_SPI_MOSI; clk = PRODIGY_SPI_CLK; @@ -602,9 +601,7 @@ static unsigned short wm_get(struct snd_ice1712 *ice, int reg) static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) { aureon_spi_write(ice, - ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ? - PRODIGY_WM_CS : AUREON_WM_CS), + (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS), (reg << 9) | (val & 0x1ff), 16); } @@ -664,17 +661,17 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -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 DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); +static DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); +static DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); +static DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); /* * Logarithmic volume values for WM8770 * Computed as 20 * Log10(255 / x) */ -static const unsigned char wm_vol[256] = { +static unsigned char wm_vol[256] = { 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, @@ -1067,14 +1064,14 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val */ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[] = { + static char *texts[] = { "CD", //AIN1 "Aux", //AIN2 "Line", //AIN3 "Mic", //AIN4 "AC97" //AIN5 }; - static const char * const universe_texts[] = { + static char *universe_texts[] = { "Aux1", //AIN1 "CD", //AIN2 "Phono", //AIN3 @@ -1140,11 +1137,11 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const char * const aureon_texts[] = { + static char *aureon_texts[] = { "CD", //RXP0 "Optical" //RXP1 }; - static const char * const prodigy_texts[] = { + static char *prodigy_texts[] = { "CD", "Coax" }; @@ -1291,14 +1288,12 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable) tmp2 = tmp = snd_ice1712_gpio_read(ice); if (enable) - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) + if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) tmp |= AUREON_HP_SEL; else tmp |= PRODIGY_HP_SEL; else - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) + if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) tmp &= ~ AUREON_HP_SEL; else tmp &= ~ PRODIGY_HP_SEL; @@ -1368,7 +1363,7 @@ static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v */ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[2] = { "128x", "64x" }; + static char *texts[2] = { "128x", "64x" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1411,7 +1406,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 +1521,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 +1587,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 +1692,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 +1824,8 @@ 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), @@ -1874,6 +1870,7 @@ static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { } }; + static int __devinit aureon_add_controls(struct snd_ice1712 *ice) { unsigned int i, counts; @@ -1901,8 +1898,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) return err; } } - else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { + else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); if (err < 0) @@ -1910,8 +1906,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) } } - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { + if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { unsigned char id; snd_ice1712_save_gpio_status(ice); id = aureon_cs8415_get(ice, CS8415_ID); @@ -1941,7 +1936,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) */ static int __devinit aureon_init(struct snd_ice1712 *ice) { - static const unsigned short wm_inits_aureon[] = { + static unsigned short wm_inits_aureon[] = { /* These come first to reduce init pop noise */ 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ @@ -1977,7 +1972,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) 0x1a, 0x000, /* -12dB ADC/R */ (unsigned short)-1 }; - static const unsigned short wm_inits_prodigy[] = { + static unsigned short wm_inits_prodigy[] = { /* These come first to reduce init pop noise */ 0x1b, 0x000, /* ADC Mux */ @@ -2019,7 +2014,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) (unsigned short)-1 }; - static const unsigned short cs_inits[] = { + static unsigned short cs_inits[] = { 0x0441, /* RUN */ 0x0180, /* no mute, OMCK output on RMCK pin */ 0x0201, /* S/PDIF source on RXP1 */ @@ -2027,7 +2022,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) (unsigned short)-1 }; unsigned int tmp; - const unsigned short *p; + unsigned short *p; int err, i; if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { @@ -2067,8 +2062,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) /* initialize WM8770 codec */ if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) + ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) p = wm_inits_prodigy; else p = wm_inits_aureon; @@ -2076,8 +2070,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) wm_put(ice, p[0], p[1]); /* initialize CS8415A codec */ - if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && - ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { + if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { for (p = cs_inits; *p != (unsigned short)-1; p++) aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); ice->spec.aureon.cs8415_mux = 1; @@ -2107,58 +2100,73 @@ 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 = { - [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xfc, /* 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_DIR2] = 0x5f, - [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, +static unsigned char aureon51_eeprom[] __devinitdata = { + 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ }; -static const 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 */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [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, +static unsigned char aureon71_eeprom[] __devinitdata = { + 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ }; -#define prodigy71_eeprom aureon71_eeprom - -static const 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 */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [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, + +static unsigned char prodigy71_eeprom[] __devinitdata = { + 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ }; -#define prodigy71xt_eeprom prodigy71lt_eeprom + +static unsigned char prodigy71lt_eeprom[] __devinitdata = { + 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ +}; + /* 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", @@ -2209,15 +2217,5 @@ const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { .eeprom_data = prodigy71lt_eeprom, .driver = "Prodigy71LT", }, - { - .subvendor = VT1724_SUBDEVICE_PRODIGY71XT, - .name = "Audiotrak Prodigy 7.1 XT", - .model = "prodigy71xt", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, - .eeprom_size = sizeof(prodigy71xt_eeprom), - .eeprom_data = prodigy71xt_eeprom, - .driver = "Prodigy71LT", - }, { } /* terminator */ }; diff --git a/trunk/sound/pci/ice1712/aureon.h b/trunk/sound/pci/ice1712/aureon.h index 79e58e88ed47..3b7bea656c57 100644 --- a/trunk/sound/pci/ice1712/aureon.h +++ b/trunk/sound/pci/ice1712/aureon.h @@ -28,17 +28,15 @@ "{Terratec,Aureon 7.1 Space},"\ "{Terratec,Aureon 7.1 Universe}," \ "{AudioTrak,Prodigy 7.1}," \ - "{AudioTrak,Prodigy 7.1 LT},"\ - "{AudioTrak,Prodigy 7.1 XT}," + "{AudioTrak,Prodigy 7.1 LT}," #define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ #define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ #define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ #define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ #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) diff --git a/trunk/sound/pci/ice1712/delta.c b/trunk/sound/pci/ice1712/delta.c index 3eeb36c6e985..af659800c9b0 100644 --- a/trunk/sound/pci/ice1712/delta.c +++ b/trunk/sound/pci/ice1712/delta.c @@ -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", diff --git a/trunk/sound/pci/ice1712/delta.h b/trunk/sound/pci/ice1712/delta.h index e65d669af639..746ebde94522 100644 --- a/trunk/sound/pci/ice1712/delta.h +++ b/trunk/sound/pci/ice1712/delta.h @@ -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[]; /* diff --git a/trunk/sound/pci/ice1712/ews.c b/trunk/sound/pci/ice1712/ews.c index 9b7ff302c072..b135389fec6c 100644 --- a/trunk/sound/pci/ice1712/ews.c +++ b/trunk/sound/pci/ice1712/ews.c @@ -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", diff --git a/trunk/sound/pci/ice1712/ews.h b/trunk/sound/pci/ice1712/ews.h index df449b4741f6..a12a0b053558 100644 --- a/trunk/sound/pci/ice1712/ews.h +++ b/trunk/sound/pci/ice1712/ews.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/hoontech.c b/trunk/sound/pci/ice1712/hoontech.c index df97313aaf83..3f27d04e7d3c 100644 --- a/trunk/sound/pci/ice1712/hoontech.c +++ b/trunk/sound/pci/ice1712/hoontech.c @@ -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", @@ -325,3 +325,4 @@ const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = }, { } /* terminator */ }; + diff --git a/trunk/sound/pci/ice1712/hoontech.h b/trunk/sound/pci/ice1712/hoontech.h index b62d6e4f6c71..1ee538b20fbf 100644 --- a/trunk/sound/pci/ice1712/hoontech.h +++ b/trunk/sound/pci/ice1712/hoontech.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/ice1712.c b/trunk/sound/pci/ice1712/ice1712.c index 830a1bbd7110..8ba31cfb9045 100644 --- a/trunk/sound/pci/ice1712/ice1712.c +++ b/trunk/sound/pci/ice1712/ice1712.c @@ -107,7 +107,7 @@ module_param_array(dxr_enable, int, NULL, 0444); MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); -static const struct pci_device_id snd_ice1712_ids[] = { +static struct pci_device_id snd_ice1712_ids[] = { { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */ { 0, } }; @@ -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, @@ -719,7 +719,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s return bytes_to_frames(substream->runtime, ptr); } -static const struct snd_pcm_hardware snd_ice1712_playback = +static struct snd_pcm_hardware snd_ice1712_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -739,7 +739,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_playback_ds = +static struct snd_pcm_hardware snd_ice1712_playback_ds = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -759,7 +759,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_ds = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_capture = +static struct snd_pcm_hardware snd_ice1712_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1133,7 +1133,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea return bytes_to_frames(substream->runtime, ptr); } -static const struct snd_pcm_hardware snd_ice1712_playback_pro = +static struct snd_pcm_hardware snd_ice1712_playback_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1153,7 +1153,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_pro = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_capture_pro = +static struct snd_pcm_hardware snd_ice1712_capture_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1378,9 +1378,9 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); +static 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 +1404,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 +1413,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 +1423,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 +1435,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 +1627,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 +1663,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 +1714,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 +1723,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 +1750,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), @@ -1811,7 +1811,7 @@ int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[] = { + static char *texts[] = { "8000", /* 0: 6 */ "9600", /* 1: 3 */ "11025", /* 2: 10 */ @@ -1840,7 +1840,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const unsigned char xlate[16] = { + static unsigned char xlate[16] = { 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10 }; unsigned char val; @@ -1864,7 +1864,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const unsigned int xrate[13] = { + static unsigned int xrate[13] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 }; @@ -1891,7 +1891,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, @@ -1902,7 +1902,7 @@ static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdat static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[] = { + static char *texts[] = { "8000", /* 0: 6 */ "9600", /* 1: 3 */ "11025", /* 2: 10 */ @@ -1931,7 +1931,7 @@ static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcont struct snd_ctl_elem_value *ucontrol) { int val; - static const unsigned int xrate[13] = { + static unsigned int xrate[13] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 }; @@ -1948,7 +1948,7 @@ static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcont static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - static const unsigned int xrate[13] = { + static unsigned int xrate[13] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000 }; @@ -1962,7 +1962,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 +2001,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 +2040,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, @@ -2054,7 +2054,7 @@ static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[] = { + static char *texts[] = { "PCM Out", /* 0 */ "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */ "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */ @@ -2207,7 +2207,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 +2215,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 +2257,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 +2290,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 +2305,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 +2329,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 **tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2658,7 +2658,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 +2667,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 **tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/trunk/sound/pci/ice1712/ice1712.h b/trunk/sound/pci/ice1712/ice1712.h index c3d9feaaf57d..ce27eac40d4e 100644 --- a/trunk/sound/pci/ice1712/ice1712.h +++ b/trunk/sound/pci/ice1712/ice1712.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -382,11 +381,6 @@ struct snd_ice1712 { unsigned short master[2]; unsigned short vol[8]; } phase28; - /* a non-standard I2C device for revo51 */ - struct revo51_spec { - struct snd_i2c_device *dev; - struct snd_pt2258 *pt2258; - } revo51; /* Hoontech-specific setting */ struct hoontech_spec { unsigned char boxbits[4]; @@ -468,14 +462,6 @@ static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice, snd_ice1712_gpio_write(ice, mask & bits); } -static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice, - unsigned int mask) -{ - ice->gpio.direction &= ~mask; - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - return (snd_ice1712_gpio_read(ice) & mask); -} - int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template, @@ -514,8 +500,8 @@ struct snd_ice1712_card_info { unsigned int mpu401_2_info_flags; const char *mpu401_1_name; const char *mpu401_2_name; - const unsigned int eeprom_size; - const unsigned char *eeprom_data; + unsigned int eeprom_size; + unsigned char *eeprom_data; }; diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 1127ebdf5fec..3e3a102e6c34 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -50,7 +50,7 @@ #include "prodigy192.h" #include "juli.h" #include "phase.h" -#include "wtm.h" + MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); @@ -64,7 +64,6 @@ MODULE_SUPPORTED_DEVICE("{" PRODIGY192_DEVICE_DESC JULI_DEVICE_DESC PHASE_DEVICE_DESC - WTM_DEVICE_DESC "{VIA,VT1720}," "{VIA,VT1724}," "{ICEnsemble,Generic ICE1724}," @@ -87,7 +86,7 @@ MODULE_PARM_DESC(model, "Use the given board model."); /* Both VT1720 and VT1724 have the same PCI IDs */ -static const struct pci_device_id snd_vt1724_ids[] = { +static struct pci_device_id snd_vt1724_ids[] = { { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } }; @@ -342,7 +341,7 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) what = 0; snd_pcm_group_for_each(pos, substream) { - const struct vt1724_pcm_reg *reg; + struct vt1724_pcm_reg *reg; s = snd_pcm_group_substream_entry(pos); reg = s->runtime->private_data; what |= reg->start; @@ -606,7 +605,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - const struct vt1724_pcm_reg *reg = substream->runtime->private_data; + struct vt1724_pcm_reg *reg = substream->runtime->private_data; spin_lock_irq(&ice->reg_lock); outl(substream->runtime->dma_addr, ice->profi_port + reg->addr); @@ -621,7 +620,7 @@ static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream) static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - const struct vt1724_pcm_reg *reg = substream->runtime->private_data; + struct vt1724_pcm_reg *reg = substream->runtime->private_data; size_t ptr; if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start)) @@ -647,21 +646,21 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr #endif } -static const struct vt1724_pcm_reg vt1724_playback_pro_reg = { +static struct vt1724_pcm_reg vt1724_playback_pro_reg = { .addr = VT1724_MT_PLAYBACK_ADDR, .size = VT1724_MT_PLAYBACK_SIZE, .count = VT1724_MT_PLAYBACK_COUNT, .start = VT1724_PDMA0_START, }; -static const struct vt1724_pcm_reg vt1724_capture_pro_reg = { +static struct vt1724_pcm_reg vt1724_capture_pro_reg = { .addr = VT1724_MT_CAPTURE_ADDR, .size = VT1724_MT_CAPTURE_SIZE, .count = VT1724_MT_CAPTURE_COUNT, .start = VT1724_RDMA0_START, }; -static const struct snd_pcm_hardware snd_vt1724_playback_pro = +static struct snd_pcm_hardware snd_vt1724_playback_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -680,7 +679,7 @@ static const struct snd_pcm_hardware snd_vt1724_playback_pro = .periods_max = 1024, }; -static const struct snd_pcm_hardware snd_vt1724_spdif = +static struct snd_pcm_hardware snd_vt1724_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -702,7 +701,7 @@ static const struct snd_pcm_hardware snd_vt1724_spdif = .periods_max = 1024, }; -static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = +static struct snd_pcm_hardware snd_vt1724_2ch_stereo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -774,7 +773,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); int chs; - runtime->private_data = (void *)&vt1724_playback_pro_reg; + runtime->private_data = &vt1724_playback_pro_reg; ice->playback_pro_substream = substream; runtime->hw = snd_vt1724_playback_pro; snd_pcm_set_sync(substream); @@ -803,7 +802,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - runtime->private_data = (void *)&vt1724_capture_pro_reg; + runtime->private_data = &vt1724_capture_pro_reg; ice->capture_pro_substream = substream; runtime->hw = snd_vt1724_2ch_stereo; snd_pcm_set_sync(substream); @@ -889,14 +888,14 @@ static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device) * SPDIF PCM */ -static const struct vt1724_pcm_reg vt1724_playback_spdif_reg = { +static struct vt1724_pcm_reg vt1724_playback_spdif_reg = { .addr = VT1724_MT_PDMA4_ADDR, .size = VT1724_MT_PDMA4_SIZE, .count = VT1724_MT_PDMA4_COUNT, .start = VT1724_PDMA4_START, }; -static const struct vt1724_pcm_reg vt1724_capture_spdif_reg = { +static struct vt1724_pcm_reg vt1724_capture_spdif_reg = { .addr = VT1724_MT_RDMA1_ADDR, .size = VT1724_MT_RDMA1_SIZE, .count = VT1724_MT_RDMA1_COUNT, @@ -954,7 +953,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - runtime->private_data = (void *)&vt1724_playback_spdif_reg; + runtime->private_data = &vt1724_playback_spdif_reg; ice->playback_con_substream = substream; if (ice->force_pdma4) { runtime->hw = snd_vt1724_2ch_stereo; @@ -986,7 +985,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - runtime->private_data = (void *)&vt1724_capture_spdif_reg; + runtime->private_data = &vt1724_capture_spdif_reg; ice->capture_con_substream = substream; if (ice->force_rdma1) { runtime->hw = snd_vt1724_2ch_stereo; @@ -1091,7 +1090,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device) * independent surround PCMs */ -static const struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { +static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { { .addr = VT1724_MT_PDMA1_ADDR, .size = VT1724_MT_PDMA1_SIZE, @@ -1137,7 +1136,7 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream) return -EBUSY; /* FIXME: should handle blocking mode properly */ } mutex_unlock(&ice->open_mutex); - runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number]; + runtime->private_data = &vt1724_playback_dma_regs[substream->number]; ice->playback_con_substream_ds[substream->number] = substream; runtime->hw = snd_vt1724_2ch_stereo; snd_pcm_set_sync(substream); @@ -1318,7 +1317,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 +1430,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 +1462,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 +1471,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 +1516,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 */ @@ -1585,7 +1584,7 @@ int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts_1724[] = { + static char *texts_1724[] = { "8000", /* 0: 6 */ "9600", /* 1: 3 */ "11025", /* 2: 10 */ @@ -1603,7 +1602,7 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, "192000", /* 14: 14 */ "IEC958 Input", /* 15: -- */ }; - static const char * const texts_1720[] = { + static char *texts_1720[] = { "8000", /* 0: 6 */ "9600", /* 1: 3 */ "11025", /* 2: 10 */ @@ -1636,7 +1635,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - static const unsigned char xlate[16] = { + static unsigned char xlate[16] = { 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10 }; unsigned char val; @@ -1695,7 +1694,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 +1733,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 +1772,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, @@ -1817,7 +1816,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift) { unsigned long val; unsigned char eitem; - static const unsigned char xlate[8] = { + static unsigned char xlate[8] = { 0, 255, 1, 2, 255, 255, 3, 4, }; @@ -1836,7 +1835,7 @@ static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift) { unsigned int old_val, nval; int change; - static const unsigned char xroute[8] = { + static unsigned char xroute[8] = { 0, /* PCM */ 2, /* PSDIN0 Left */ 3, /* PSDIN0 Right */ @@ -1892,7 +1891,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 +1899,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 +1935,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 +1947,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, @@ -1959,7 +1958,6 @@ static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_prodigy192_cards, snd_vt1724_juli_cards, snd_vt1724_phase_cards, - snd_vt1724_wtm_cards, NULL, }; @@ -2009,7 +2007,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 **tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2308,7 +2306,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 **tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/trunk/sound/pci/ice1712/juli.c b/trunk/sound/pci/ice1712/juli.c index d88172fa95da..5176b41ea9d3 100644 --- a/trunk/sound/pci/ice1712/juli.c +++ b/trunk/sound/pci/ice1712/juli.c @@ -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 = { @@ -146,7 +146,7 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice) */ static int __devinit juli_init(struct snd_ice1712 *ice) { - static const unsigned char ak4114_init_vals[] = { + static unsigned char ak4114_init_vals[] = { /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S, /* AK4114_REG_IO0 */ AK4114_TX1E, @@ -154,7 +154,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice) /* AK4114_REG_INT0_MASK */ 0, /* AK4114_REG_INT1_MASK */ 0 }; - static const unsigned char ak4114_init_txcsb[] = { + static unsigned char ak4114_init_txcsb[] = { 0x41, 0x02, 0x2c, 0x00, 0x00 }; int err; @@ -206,24 +206,24 @@ 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 = { - [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ - [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] = 0x9f, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x7f, - [ICE_EEP2_GPIO_MASK] = 0x9f, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x7f, - [ICE_EEP2_GPIO_STATE] = 0x16, /* internal clock, multiple 1x, 48kHz */ - [ICE_EEP2_GPIO_STATE1] = 0x80, /* mute */ - [ICE_EEP2_GPIO_STATE2] = 0x00, +static unsigned char juli_eeprom[] __devinitdata = { + 0x20, /* SYSCONF: clock 512, mpu401, 1xADC, 1xDACs */ + 0x80, /* ACLINK: I2S */ + 0xf8, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0x9f, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x7f, /* GPIO_DIR2 */ + 0x9f, /* GPIO_MASK */ + 0xff, /* GPIO_MASK1 */ + 0x7f, /* GPIO_MASK2 */ + 0x16, /* GPIO_STATE: internal clock, multiple 1x, 48kHz */ + 0x80, /* GPIO_STATE1: mute */ + 0x00, /* GPIO_STATE2 */ }; /* 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@", diff --git a/trunk/sound/pci/ice1712/juli.h b/trunk/sound/pci/ice1712/juli.h index 1b9294f8bce3..d9f8534fd92e 100644 --- a/trunk/sound/pci/ice1712/juli.h +++ b/trunk/sound/pci/ice1712/juli.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/phase.c b/trunk/sound/pci/ice1712/phase.c index 0751718f4d7b..e08d73f4ff85 100644 --- a/trunk/sound/pci/ice1712/phase.c +++ b/trunk/sound/pci/ice1712/phase.c @@ -71,7 +71,7 @@ * Logarithmic volume values for WM8770 * Computed as 20 * Log10(255 / x) */ -static const unsigned char wm_vol[256] = { +static unsigned char wm_vol[256] = { 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, @@ -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,36 +152,36 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) return 0; } -static const unsigned char phase22_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ - [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0xff, - [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, +static unsigned char phase22_eeprom[] __devinitdata = { + 0x00, /* SYSCONF: 1xADC, 1xDACs */ + 0x80, /* ACLINK: I2S */ + 0xf8, /* I2S: vol, 96k, 24bit*/ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xFF, /* GPIO_DIR */ + 0xFF, /* GPIO_DIR1 */ + 0xFF, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE: */ + 0x00, /* GPIO_STATE1: */ + 0x00, /* GPIO_STATE2 */ }; -static const 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 */ - [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x5f, - [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, +static unsigned char phase28_eeprom[] __devinitdata = { + 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xfc, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x5f, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ }; /* @@ -343,7 +343,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ static int __devinit phase28_init(struct snd_ice1712 *ice) { - static const unsigned short wm_inits_phase28[] = { + static unsigned short wm_inits_phase28[] = { /* These come first to reduce init pop noise */ 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ @@ -382,7 +382,7 @@ static int __devinit phase28_init(struct snd_ice1712 *ice) unsigned int tmp; struct snd_akm4xxx *ak; - const unsigned short *p; + unsigned short *p; int i; ice->num_total_dacs = 8; @@ -697,10 +697,10 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct return 0; } -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 DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); +static 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", diff --git a/trunk/sound/pci/ice1712/phase.h b/trunk/sound/pci/ice1712/phase.h index ad379a99bf92..13e841b55488 100644 --- a/trunk/sound/pci/ice1712/phase.h +++ b/trunk/sound/pci/ice1712/phase.h @@ -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) diff --git a/trunk/sound/pci/ice1712/pontis.c b/trunk/sound/pci/ice1712/pontis.c index 9552497f0765..6c74c2d2e7f3 100644 --- a/trunk/sound/pci/ice1712/pontis.c +++ b/trunk/sound/pci/ice1712/pontis.c @@ -434,7 +434,7 @@ static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned */ static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static const char * const texts[] = { + static char *texts[] = { "Coax", /* RXP0 */ "Optical", /* RXP1 */ "CD", /* RXP2 */ @@ -565,13 +565,13 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el return changed; } -static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); +static 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 | @@ -741,7 +741,7 @@ static int __devinit pontis_add_controls(struct snd_ice1712 *ice) */ static int __devinit pontis_init(struct snd_ice1712 *ice) { - static const unsigned short wm_inits[] = { + static unsigned short wm_inits[] = { /* These come first to reduce init pop noise */ WM_ADC_MUX, 0x00c0, /* ADC mute */ WM_DAC_MUTE, 0x0001, /* DAC softmute */ @@ -750,7 +750,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) WM_POWERDOWN, 0x0008, /* All power-up except HP */ WM_RESET, 0x0000, /* reset */ }; - static const unsigned short wm_inits2[] = { + static unsigned short wm_inits2[] = { WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ @@ -776,7 +776,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) WM_DAC_MUTE, 0x0000, /* DAC unmute */ WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ }; - static const unsigned char cs_inits[] = { + static unsigned char cs_inits[] = { 0x04, 0x80, /* RUN, RXP0 */ 0x05, 0x05, /* slave, 24bit */ 0x01, 0x00, @@ -826,24 +826,24 @@ 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 = { - [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ - [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] = 0x07, - [ICE_EEP2_GPIO_DIR1] = 0x00, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* ignored */ - [ICE_EEP2_GPIO_MASK] = 0x0f, /* 4-7 reserved for CS8416 */ - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* ignored */ - [ICE_EEP2_GPIO_STATE] = 0x06, /* 0-low, 1-high, 2-high */ - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* ignored */ +static unsigned char pontis_eeprom[] __devinitdata = { + 0x08, /* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */ + 0x80, /* ACLINK: I2S */ + 0xf8, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0x07, /* GPIO_DIR */ + 0x00, /* GPIO_DIR1 */ + 0x00, /* GPIO_DIR2 (ignored) */ + 0x0f, /* GPIO_MASK (4-7 reserved for CS8416) */ + 0xff, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 (ignored) */ + 0x06, /* GPIO_STATE (0-low, 1-high, 2-high) */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 (ignored) */ }; /* 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", diff --git a/trunk/sound/pci/ice1712/pontis.h b/trunk/sound/pci/ice1712/pontis.h index 1a418255c19e..d0d1378b935c 100644 --- a/trunk/sound/pci/ice1712/pontis.h +++ b/trunk/sound/pci/ice1712/pontis.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/prodigy192.c b/trunk/sound/pci/ice1712/prodigy192.c index 31cc66eb9f8f..41b2605daa3a 100644 --- a/trunk/sound/pci/ice1712/prodigy192.c +++ b/trunk/sound/pci/ice1712/prodigy192.c @@ -357,14 +357,14 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl } #endif -static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); +static DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); +static 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", @@ -475,7 +475,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) */ static int __devinit prodigy192_init(struct snd_ice1712 *ice) { - static const unsigned short stac_inits_prodigy[] = { + static unsigned short stac_inits_prodigy[] = { STAC946X_RESET, 0, /* STAC946X_MASTER_VOLUME, 0, STAC946X_LF_VOLUME, 0, @@ -486,7 +486,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) STAC946X_LFE_VOLUME, 0,*/ (unsigned short)-1 }; - const unsigned short *p; + unsigned short *p; /* prodigy 192 */ ice->num_total_dacs = 6; @@ -506,25 +506,25 @@ 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 */ - [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_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, +static unsigned char prodigy71_eeprom[] __devinitdata = { + 0x2b, /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */ + 0x80, /* ACLINK: I2S */ + 0xf8, /* I2S: vol, 96k, 24bit, 192k */ + 0xc3, /* SPDIF: out-en, out-int, spdif-in */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0xbf, /* GPIO_DIR2 */ + 0x00, /* GPIO_MASK */ + 0x00, /* GPIO_MASK1 */ + 0x00, /* GPIO_MASK2 */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* GPIO_STATE2 */ }; /* 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", diff --git a/trunk/sound/pci/ice1712/prodigy192.h b/trunk/sound/pci/ice1712/prodigy192.h index 2fa2e62b9e04..94c824e24e06 100644 --- a/trunk/sound/pci/ice1712/prodigy192.h +++ b/trunk/sound/pci/ice1712/prodigy192.h @@ -6,6 +6,6 @@ #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ -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 */ diff --git a/trunk/sound/pci/ice1712/revo.c b/trunk/sound/pci/ice1712/revo.c index 025a7e8497c3..bf98ea34feb0 100644 --- a/trunk/sound/pci/ice1712/revo.c +++ b/trunk/sound/pci/ice1712/revo.c @@ -83,143 +83,39 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) snd_akm4xxx_reset(ak, 0); } -/* - * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1) - */ - -static void revo_i2c_start(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - snd_ice1712_save_gpio_status(ice); -} - -static void revo_i2c_stop(struct snd_i2c_bus *bus) -{ - struct snd_ice1712 *ice = bus->private_data; - snd_ice1712_restore_gpio_status(ice); -} - -static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned int mask, val; - - val = 0; - if (clock) - val |= VT1724_REVO_I2C_CLOCK; /* write SCL */ - if (data) - val |= VT1724_REVO_I2C_DATA; /* write SDA */ - mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA; - ice->gpio.direction &= ~mask; - ice->gpio.direction |= val; - snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - snd_ice1712_gpio_set_mask(ice, ~mask); -} - -static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data) -{ - struct snd_ice1712 *ice = bus->private_data; - unsigned int val = 0; - - if (clk) - val |= VT1724_REVO_I2C_CLOCK; - if (data) - val |= VT1724_REVO_I2C_DATA; - snd_ice1712_gpio_write_bits(ice, - VT1724_REVO_I2C_DATA | - VT1724_REVO_I2C_CLOCK, val); - udelay(5); -} - -static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack) -{ - struct snd_ice1712 *ice = bus->private_data; - int bit; - - if (ack) - udelay(5); - bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0; - return bit; -} - -static struct snd_i2c_bit_ops revo51_bit_ops = { - .start = revo_i2c_start, - .stop = revo_i2c_stop, - .direction = revo_i2c_direction, - .setlines = revo_i2c_setlines, - .getdata = revo_i2c_getdata, -}; - -static int revo51_i2c_init(struct snd_ice1712 *ice, - struct snd_pt2258 *pt) -{ - int err; - - /* create the I2C bus */ - err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c); - if (err < 0) - return err; - - ice->i2c->private_data = ice; - ice->i2c->hw_ops.bit = &revo51_bit_ops; - - /* create the I2C device */ - err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, - &ice->spec.revo51.dev); - if (err < 0) - return err; - - pt->card = ice->card; - pt->i2c_bus = ice->i2c; - pt->i2c_dev = ice->spec.revo51.dev; - ice->spec.revo51.pt2258 = pt; - - snd_pt2258_reset(pt); - - return 0; -} - /* * initialize the chips on M-Audio Revolution cards */ #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } -static const struct snd_akm4xxx_dac_channel revo71_front[] = { +static struct snd_akm4xxx_dac_channel revo71_front[] = { AK_DAC("PCM Playback Volume", 2) }; -static const struct snd_akm4xxx_dac_channel revo71_surround[] = { +static struct snd_akm4xxx_dac_channel revo71_surround[] = { AK_DAC("PCM Center Playback Volume", 1), AK_DAC("PCM LFE Playback Volume", 1), AK_DAC("PCM Side Playback Volume", 2), AK_DAC("PCM Rear Playback Volume", 2), }; -static const struct snd_akm4xxx_dac_channel revo51_dac[] = { +static struct snd_akm4xxx_dac_channel revo51_dac[] = { AK_DAC("PCM Playback Volume", 2), AK_DAC("PCM Center Playback Volume", 1), AK_DAC("PCM LFE Playback Volume", 1), AK_DAC("PCM Rear Playback Volume", 2), }; -static const char *revo51_adc_input_names[] = { - "Mic", - "Line", - "CD", - NULL -}; - -static const struct snd_akm4xxx_adc_channel revo51_adc[] = { +static struct snd_akm4xxx_adc_channel revo51_adc[] = { { .name = "PCM Capture Volume", .switch_name = "PCM Capture Switch", - .num_channels = 2, - .input_names = revo51_adc_input_names + .num_channels = 2 }, }; -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 +124,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 +136,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 +146,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 +158,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,213 +167,36 @@ 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, .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_addr = VT1724_REVO_CS1, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, + .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, + .cs_addr = VT1724_REVO_CS1 | VT1724_REVO_CS2, + .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, .add_flags = VT1724_REVO_CCLK, /* high at init */ .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, .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .cs_addr = VT1724_REVO_CS0, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, - .add_flags = VT1724_REVO_CCLK, /* high at init */ - .mask_flags = 0, -}; - -static struct snd_pt2258 ptc_revo51_volume; - -/* AK4358 for AP192 DAC, AK5385A for ADC */ -static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) -{ - struct snd_ice1712 *ice = ak->private_data[0]; - - revo_set_rate_val(ak, rate); - -#if 1 /* FIXME: do we need this procedure? */ - /* reset DFS pin of AK5385A for ADC, too */ - /* DFS0 (pin 18) -- GPIO10 pin 77 */ - snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_write_bits(ice, 1 << 10, - rate > 48000 ? (1 << 10) : 0); - snd_ice1712_restore_gpio_status(ice); -#endif -} - -static const struct snd_akm4xxx_dac_channel ap192_dac[] = { - AK_DAC("PCM Playback Volume", 2) -}; - -static const struct snd_akm4xxx akm_ap192 __devinitdata = { - .type = SND_AK4358, - .num_dacs = 2, - .ops = { - .set_rate_val = ap192_set_rate_val - }, - .dac_info = ap192_dac, -}; - -static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { - .caddr = 2, - .cif = 0, - .data_mask = VT1724_REVO_CDOUT, - .clk_mask = VT1724_REVO_CCLK, - .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3, - .cs_addr = VT1724_REVO_CS3, - .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3, + .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, + .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2, + .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, .add_flags = VT1724_REVO_CCLK, /* high at init */ .mask_flags = 0, }; -#if 0 -/* FIXME: ak4114 makes the sound much lower due to some confliction, - * so let's disable it right now... - */ -#define BUILD_AK4114_AP192 -#endif - -#ifdef BUILD_AK4114_AP192 -/* AK4114 support on Audiophile 192 */ -/* CDTO (pin 32) -- GPIO2 pin 52 - * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358) - * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358) - * CSN (pin 35) -- GPIO7 pin 59 - */ -#define AK4114_ADDR 0x00 - -static void write_data(struct snd_ice1712 *ice, unsigned int gpio, - unsigned int data, int idx) -{ - for (; idx >= 0; idx--) { - /* drop clock */ - gpio &= ~VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* set data */ - if (data & (1 << idx)) - gpio |= VT1724_REVO_CDOUT; - else - gpio &= ~VT1724_REVO_CDOUT; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* raise clock */ - gpio |= VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } -} - -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_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - /* read data */ - if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN) - data |= (1 << idx); - udelay(1); - /* raise clock */ - gpio |= VT1724_REVO_CCLK; - snd_ice1712_gpio_write(ice, gpio); - udelay(1); - } - return data; -} - -static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) -{ - unsigned int tmp; - - snd_ice1712_save_gpio_status(ice); - tmp = snd_ice1712_gpio_read(ice); - tmp |= VT1724_REVO_CCLK; /* high at init */ - tmp |= VT1724_REVO_CS0; - tmp &= ~VT1724_REVO_CS3; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - return tmp; -} - -static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) -{ - tmp |= VT1724_REVO_CS3; - tmp |= VT1724_REVO_CS0; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - snd_ice1712_restore_gpio_status(ice); -} - -static void ap192_ak4114_write(void *private_data, unsigned char addr, - unsigned char data) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp, addrdata; - - tmp = ap192_4wire_start(ice); - addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); - addrdata = (addrdata << 8) | data; - write_data(ice, tmp, addrdata, 15); - ap192_4wire_finish(ice, tmp); -} - -static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) -{ - struct snd_ice1712 *ice = private_data; - unsigned int tmp; - unsigned char data; - - tmp = ap192_4wire_start(ice); - write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); - data = read_data(ice, tmp, 7); - ap192_4wire_finish(ice, tmp); - return data; -} - -static int ap192_ak4114_init(struct snd_ice1712 *ice) -{ - static const unsigned char ak4114_init_vals[] = { - AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, - AK4114_DIF_I24I2S, - AK4114_TX1E, - AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), - 0, - 0 - }; - static const unsigned char ak4114_init_txcsb[] = { - 0x41, 0x02, 0x2c, 0x00, 0x00 - }; - struct ak4114 *ak; - int err; - - return snd_ak4114_create(ice->card, - ap192_ak4114_read, - ap192_ak4114_write, - ak4114_init_vals, ak4114_init_txcsb, - ice, &ak); -} -#endif /* BUILD_AK4114_AP192 */ - static int __devinit revo_init(struct snd_ice1712 *ice) { struct snd_akm4xxx *ak; @@ -494,10 +213,6 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ice->num_total_dacs = 6; ice->num_total_adcs = 2; break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - ice->num_total_dacs = 2; - ice->num_total_adcs = 2; - break; default: snd_BUG(); return -EINVAL; @@ -520,28 +235,14 @@ static int __devinit revo_init(struct snd_ice1712 *ice) break; case VT1724_SUBDEVICE_REVOLUTION51: ice->akm_codecs = 2; - err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, - &akm_revo51_priv, ice); - if (err < 0) + if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, &akm_revo51_priv, ice)) < 0) return err; - err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc, + err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo51_adc, &akm_revo51_adc_priv, ice); if (err < 0) return err; - err = revo51_i2c_init(ice, &ptc_revo51_volume); - if (err < 0) - return err; - /* unmute all codecs */ - snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, - VT1724_REVO_MUTE); - break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - ice->akm_codecs = 1; - err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv, - ice); - if (err < 0) - return err; - + /* unmute all codecs - needed! */ + snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); break; } @@ -555,34 +256,16 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_REVOLUTION71: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; - break; case VT1724_SUBDEVICE_REVOLUTION51: err = snd_ice1712_akm4xxx_build_controls(ice); if (err < 0) return err; - err = snd_pt2258_build_controls(ice->spec.revo51.pt2258); - if (err < 0) - return err; - break; - case VT1724_SUBDEVICE_AUDIOPHILE192: - err = snd_ice1712_akm4xxx_build_controls(ice); - if (err < 0) - return err; -#ifdef BUILD_AK4114_AP192 - err = ap192_ak4114_init(ice); - if (err < 0) - return err; -#endif - break; } return 0; } /* 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", @@ -597,12 +280,5 @@ const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { .chip_init = revo_init, .build_controls = revo_add_controls, }, - { - .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192, - .name = "M Audio Audiophile192", - .model = "ap192", - .chip_init = revo_init, - .build_controls = revo_add_controls, - }, { } /* terminator */ }; diff --git a/trunk/sound/pci/ice1712/revo.h b/trunk/sound/pci/ice1712/revo.h index 2a24488fad80..efbb86ec3289 100644 --- a/trunk/sound/pci/ice1712/revo.h +++ b/trunk/sound/pci/ice1712/revo.h @@ -26,15 +26,13 @@ #define REVO_DEVICE_DESC \ "{MidiMan M Audio,Revolution 7.1},"\ - "{MidiMan M Audio,Revolution 5.1},"\ - "{MidiMan M Audio,Audiophile 192}," + "{MidiMan M Audio,Revolution 5.1}," #define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 #define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 -#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[]; /* @@ -44,12 +42,9 @@ extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[]; #define VT1724_REVO_CCLK 0x02 #define VT1724_REVO_CDIN 0x04 /* not used */ #define VT1724_REVO_CDOUT 0x08 -#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for (revo51) */ +#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for Rev. 5.1 */ #define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */ -#define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ -#define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ -#define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ -#define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */ +#define VT1724_REVO_CS2 0x40 /* surround AKM4355 chipselect */ #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ #endif /* __SOUND_REVO_H */ diff --git a/trunk/sound/pci/ice1712/vt1720_mobo.c b/trunk/sound/pci/ice1712/vt1720_mobo.c index 72b060d63c29..7ca263c13091 100644 --- a/trunk/sound/pci/ice1712/vt1720_mobo.c +++ b/trunk/sound/pci/ice1712/vt1720_mobo.c @@ -30,7 +30,6 @@ #include #include "ice1712.h" -#include "envy24ht.h" #include "vt1720_mobo.h" @@ -56,41 +55,41 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) /* EEPROM image */ -static const unsigned char k8x800_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ - [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ - [ICE_EEP2_I2S] = 0x00, /* - */ - [ICE_EEP2_SPDIF] = 0x00, /* - */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */ - [ICE_EEP2_GPIO_MASK] = 0xff, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */ - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ +static unsigned char k8x800_eeprom[] __devinitdata = { + 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */ + 0x02, /* ACLINK: ACLINK, packed */ + 0x00, /* I2S: - */ + 0x00, /* SPDIF: - */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x00, /* - */ + 0xff, /* GPIO_MASK */ + 0xff, /* GPIO_MASK1 */ + 0x00, /* - */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* - */ }; -static const unsigned char sn25p_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ - [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ - [ICE_EEP2_I2S] = 0x00, /* - */ - [ICE_EEP2_SPDIF] = 0x41, /* - */ - [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, - [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */ - [ICE_EEP2_GPIO_MASK] = 0xff, - [ICE_EEP2_GPIO_MASK1] = 0xff, - [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */ - [ICE_EEP2_GPIO_STATE] = 0x00, - [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ +static unsigned char sn25p_eeprom[] __devinitdata = { + 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */ + 0x02, /* ACLINK: ACLINK, packed */ + 0x00, /* I2S: - */ + 0x41, /* SPDIF: - */ + 0xff, /* GPIO_DIR */ + 0xff, /* GPIO_DIR1 */ + 0x00, /* - */ + 0xff, /* GPIO_MASK */ + 0xff, /* GPIO_MASK1 */ + 0x00, /* - */ + 0x00, /* GPIO_STATE */ + 0x00, /* GPIO_STATE1 */ + 0x00, /* - */ }; /* 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", diff --git a/trunk/sound/pci/ice1712/vt1720_mobo.h b/trunk/sound/pci/ice1712/vt1720_mobo.h index 70af3ad64a5d..0b1b0ee1bea7 100644 --- a/trunk/sound/pci/ice1712/vt1720_mobo.h +++ b/trunk/sound/pci/ice1712/vt1720_mobo.h @@ -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 */ diff --git a/trunk/sound/pci/ice1712/wtm.c b/trunk/sound/pci/ice1712/wtm.c deleted file mode 100644 index 4a706b16a0b9..000000000000 --- a/trunk/sound/pci/ice1712/wtm.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * - * Lowlevel functions for Ego Sys Waveterminal 192M - * - * Copyright (c) 2006 Guedez Clement - * Some functions are taken from the Prodigy192 driver - * source - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "ice1712.h" -#include "envy24ht.h" -#include "wtm.h" -#include "stac946x.h" - - -/* - * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus - */ -static inline void stac9460_put(struct snd_ice1712 *ice, int reg, - unsigned char val) -{ - snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val); -} - -static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg) -{ - return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg); -} - -/* - * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus - */ -static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg, - unsigned char val) -{ - snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val); -} - -static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg) -{ - return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg); -} - - -/* - * DAC mute control - */ -static int stac9460_dac_mute_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; - return 0; -} - -static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int idx, id; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - id = 0; - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - } - if (id < 6) - val = stac9460_get(ice, idx); - else - val = stac9460_2_get(ice,idx - 6); - ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; - return 0; -} - -static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int id, idx; - int change; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - old = stac9460_get(ice, idx); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | - (old & ~0x80); - change = (new != old); - if (change) { - stac9460_put(ice, idx, new); - stac9460_2_put(ice, idx, new); - } - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - if (id < 6) - old = stac9460_get(ice, idx); - else - old = stac9460_2_get(ice, idx - 6); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | - (old & ~0x80); - change = (new != old); - if (change) { - if (id < 6) - stac9460_put(ice, idx, new); - else - stac9460_2_put(ice, idx - 6, new); - } - } - return change; -} - -/* - * DAC volume attenuation mixer control - */ -static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute */ - uinfo->value.integer.max = 0x7f; /* 0dB */ - return 0; -} - -static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx, id; - unsigned char vol; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - id = 0; - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - } - if (id < 6) - vol = stac9460_get(ice, idx) & 0x7f; - else - vol = stac9460_2_get(ice, idx - 6) & 0x7f; - ucontrol->value.integer.value[0] = 0x7f - vol; - return 0; -} - -static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int idx, id; - unsigned char tmp, ovol, nvol; - int change; - - if (kcontrol->private_value) { - idx = STAC946X_MASTER_VOLUME; - nvol = ucontrol->value.integer.value[0]; - tmp = stac9460_get(ice, idx); - ovol = 0x7f - (tmp & 0x7f); - change = (ovol != nvol); - if (change) { - stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - } - } else { - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - idx = id + STAC946X_LF_VOLUME; - nvol = ucontrol->value.integer.value[0]; - if (id < 6) - tmp = stac9460_get(ice, idx); - else - tmp = stac9460_2_get(ice, idx - 6); - ovol = 0x7f - (tmp & 0x7f); - change = (ovol != nvol); - if (change) { - if (id < 6) - stac9460_put(ice, idx, (0x7f - nvol) | - (tmp & 0x80)); - else - stac9460_2_put(ice, idx-6, (0x7f - nvol) | - (tmp & 0x80)); - } - } - return change; -} - -/* - * ADC mute control - */ -static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char val; - int i, id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i); - ucontrol->value.integer.value[i] = ~val>>7 & 0x1; - } - } else { - for (i = 0; i < 2; ++i) { - val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i); - ucontrol->value.integer.value[i] = ~val>>7 & 0x1; - } - } - return 0; -} - -static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - unsigned char new, old; - int i, reg, id; - int change; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - old = stac9460_get(ice, reg); - new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); - change = (new != old); - if (change) - stac9460_put(ice, reg, new); - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - old = stac9460_2_get(ice, reg); - new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); - change = (new != old); - if (change) - stac9460_2_put(ice, reg, new); - } - } - return change; -} - -/* - *ADC gain mixer control - */ -static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; /* 0dB */ - uinfo->value.integer.max = 0x0f; /* 22.5dB */ - return 0; -} - -static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg, id; - unsigned char vol; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - vol = stac9460_get(ice, reg) & 0x0f; - ucontrol->value.integer.value[i] = 0x0f - vol; - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - vol = stac9460_2_get(ice, reg) & 0x0f; - ucontrol->value.integer.value[i] = 0x0f - vol; - } - } - return 0; -} - -static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - int i, reg, id; - unsigned char ovol, nvol; - int change; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i]; - ovol = 0x0f - stac9460_get(ice, reg); - change = ((ovol & 0x0f) != nvol); - if (change) - stac9460_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); - } - } else { - for (i = 0; i < 2; ++i) { - reg = STAC946X_MIC_L_VOLUME + i; - nvol = ucontrol->value.integer.value[i]; - ovol = 0x0f - stac9460_2_get(ice, reg); - change = ((ovol & 0x0f) != nvol); - if (change) - stac9460_2_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); - } - } - return change; -} - -/* - * MIC / LINE switch fonction - */ - -static int stac9460_mic_sw_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 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; - int id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) - val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - else - val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); - ucontrol->value.integer.value[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, id; - - id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (id == 0) - old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); - else - old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80); - change = (new != old); - if (change) { - if (id == 0) - stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); - else - stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); - } - return change; -} - -/* - * Control tabs - */ -static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - .private_value = 1 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "MIC/Line switch", - .count = 2, - .info = stac9460_mic_sw_info, - .get = stac9460_mic_sw_get, - .put = stac9460_mic_sw_put, - - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Switch", - .count = 8, - .info = stac9460_dac_mute_info, - .get = stac9460_dac_mute_get, - .put = stac9460_dac_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Volume", - .count = 8, - .info = stac9460_dac_vol_info, - .get = stac9460_dac_vol_get, - .put = stac9460_dac_vol_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Switch", - .count = 2, - .info = stac9460_adc_mute_info, - .get = stac9460_adc_mute_get, - .put = stac9460_adc_mute_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Volume", - .count = 2, - .info = stac9460_adc_vol_info, - .get = stac9460_adc_vol_get, - .put = stac9460_adc_vol_put, - - } -}; - - - -/*INIT*/ -static int __devinit wtm_add_controls(struct snd_ice1712 *ice) -{ - unsigned int i; - int err; - - for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) { - err = snd_ctl_add(ice->card, - snd_ctl_new1(&stac9640_controls[i], ice)); - if (err < 0) - return err; - } - return 0; -} - -static int __devinit wtm_init(struct snd_ice1712 *ice) -{ - static unsigned short stac_inits_prodigy[] = { - STAC946X_RESET, 0, - (unsigned short)-1 - }; - unsigned short *p; - - /*WTM 192M*/ - ice->num_total_dacs = 8; - ice->num_total_adcs = 4; - ice->force_rdma1 = 1; - - /*initialize codec*/ - p = stac_inits_prodigy; - for (; *p != (unsigned short)-1; p += 2) { - stac9460_put(ice, p[0], p[1]); - stac9460_2_put(ice, p[0], p[1]); - } - return 0; -} - - -static unsigned char wtm_eeprom[] __devinitdata = { - 0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */ - 0x80, /* ACLINK : I2S */ - 0xf8, /* I2S: vol; 96k, 24bit, 192k */ - 0xc1 /*SPDIF: out-en, spidf ext out*/, - 0x9f, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x7f, /* GPIO_DIR2 */ - 0x9f, /* GPIO_MASK */ - 0xff, /* GPIO_MASK1 */ - 0x7f, /* GPIO_MASK2 */ - 0x16, /* GPIO_STATE */ - 0x80, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - - -/*entry point*/ -struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_WTM, - .name = "ESI Waveterminal 192M", - .model = "WT192M", - .chip_init = wtm_init, - .build_controls = wtm_add_controls, - .eeprom_size = sizeof(wtm_eeprom), - .eeprom_data = wtm_eeprom, - }, - {} /*terminator*/ -}; diff --git a/trunk/sound/pci/ice1712/wtm.h b/trunk/sound/pci/ice1712/wtm.h deleted file mode 100644 index 03a394e442f1..000000000000 --- a/trunk/sound/pci/ice1712/wtm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __SOUND_WTM_H -#define __SOUND_WTM_H - -/* ID */ -#define WTM_DEVICE_DESC "{EGO SYS INC,WaveTerminal 192M}," -#define VT1724_SUBDEVICE_WTM 0x36495345 /* WT192M ver1.0 */ - -/* - *chip addresses on I2C bus - */ - -#define AK4114_ADDR 0x20 /*S/PDIF receiver*/ -#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */ -#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */ - - -extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[]; - -#endif /* __SOUND_WTM_H */ - diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index a289abfc7172..30aaa6092a84 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -71,7 +71,6 @@ static char *ac97_quirk; static int buggy_semaphore; static int buggy_irq = -1; /* auto-check */ static int xbox; -static int spdif_aclink = -1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); @@ -87,8 +86,6 @@ module_param(buggy_irq, bool, 0444); MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); module_param(xbox, bool, 0444); MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); -module_param(spdif_aclink, int, 0444); -MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); /* just for backward compatibility */ static int enable; @@ -371,8 +368,12 @@ struct intel8x0 { int irq; - void __iomem *addr; - void __iomem *bmaddr; + unsigned int mmio; + unsigned long addr; + void __iomem *remap_addr; + unsigned int bm_mmio; + unsigned long bmaddr; + void __iomem *remap_bmaddr; struct pci_dev *pci; struct snd_card *card; @@ -445,48 +446,72 @@ MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids); * Lowlevel I/O - busmaster */ -static inline u8 igetbyte(struct intel8x0 *chip, u32 offset) +static u8 igetbyte(struct intel8x0 *chip, u32 offset) { - return ioread8(chip->bmaddr + offset); + if (chip->bm_mmio) + return readb(chip->remap_bmaddr + offset); + else + return inb(chip->bmaddr + offset); } -static inline u16 igetword(struct intel8x0 *chip, u32 offset) +static u16 igetword(struct intel8x0 *chip, u32 offset) { - return ioread16(chip->bmaddr + offset); + if (chip->bm_mmio) + return readw(chip->remap_bmaddr + offset); + else + return inw(chip->bmaddr + offset); } -static inline u32 igetdword(struct intel8x0 *chip, u32 offset) +static u32 igetdword(struct intel8x0 *chip, u32 offset) { - return ioread32(chip->bmaddr + offset); + if (chip->bm_mmio) + return readl(chip->remap_bmaddr + offset); + else + return inl(chip->bmaddr + offset); } -static inline void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) +static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) { - iowrite8(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writeb(val, chip->remap_bmaddr + offset); + else + outb(val, chip->bmaddr + offset); } -static inline void iputword(struct intel8x0 *chip, u32 offset, u16 val) +static void iputword(struct intel8x0 *chip, u32 offset, u16 val) { - iowrite16(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writew(val, chip->remap_bmaddr + offset); + else + outw(val, chip->bmaddr + offset); } -static inline void iputdword(struct intel8x0 *chip, u32 offset, u32 val) +static void iputdword(struct intel8x0 *chip, u32 offset, u32 val) { - iowrite32(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writel(val, chip->remap_bmaddr + offset); + else + outl(val, chip->bmaddr + offset); } /* * Lowlevel I/O - AC'97 registers */ -static inline u16 iagetword(struct intel8x0 *chip, u32 offset) +static u16 iagetword(struct intel8x0 *chip, u32 offset) { - return ioread16(chip->addr + offset); + if (chip->mmio) + return readw(chip->remap_addr + offset); + else + return inw(chip->addr + offset); } -static inline void iaputword(struct intel8x0 *chip, u32 offset, u16 val) +static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) { - iowrite16(val, chip->addr + offset); + if (chip->mmio) + writew(val, chip->remap_addr + offset); + else + outw(val, chip->addr + offset); } /* @@ -1581,14 +1606,10 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip) case DEVICE_INTEL_ICH4: tbl = intel_pcms; tblsize = ARRAY_SIZE(intel_pcms); - if (spdif_aclink) - tblsize--; break; case DEVICE_NFORCE: tbl = nforce_pcms; tblsize = ARRAY_SIZE(nforce_pcms); - if (spdif_aclink) - tblsize--; break; case DEVICE_ALI: tbl = ali_pcms; @@ -2047,26 +2068,24 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, }; chip->spdif_idx = -1; /* use PCMOUT (or disabled) */ - if (!spdif_aclink) { - switch (chip->device_type) { - case DEVICE_NFORCE: - chip->spdif_idx = NVD_SPBAR; - break; - case DEVICE_ALI: - chip->spdif_idx = ALID_AC97SPDIFOUT; - break; - case DEVICE_INTEL_ICH4: - chip->spdif_idx = ICHD_SPBAR; - break; - }; - } + switch (chip->device_type) { + case DEVICE_NFORCE: + chip->spdif_idx = NVD_SPBAR; + break; + case DEVICE_ALI: + chip->spdif_idx = ALID_AC97SPDIFOUT; + break; + case DEVICE_INTEL_ICH4: + chip->spdif_idx = ICHD_SPBAR; + break; + }; chip->in_ac97_init = 1; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = chip; ac97.private_free = snd_intel8x0_mixer_free_ac97; - ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_MODEM; if (chip->xbox) ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR; if (chip->device_type != DEVICE_ALI) { @@ -2182,11 +2201,11 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20) chip->smp20bit = 1; } - if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { + if (chip->device_type == DEVICE_NFORCE) { /* 48kHz only */ chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000; } - if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { + if (chip->device_type == DEVICE_INTEL_ICH4) { /* use slot 10/11 for SPDIF */ u32 val; val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK; @@ -2314,7 +2333,7 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) /* unmute the output on SIS7012 */ iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); } - if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { + if (chip->device_type == DEVICE_NFORCE) { /* enable SPDIF interrupt */ unsigned int val; pci_read_config_dword(chip->pci, 0x4c, &val); @@ -2407,7 +2426,7 @@ static int snd_intel8x0_free(struct intel8x0 *chip) /* reset channels */ for (i = 0; i < chip->bdbars_count; i++) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); - if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) { + if (chip->device_type == DEVICE_NFORCE) { /* stop the spdif interrupt */ unsigned int val; pci_read_config_dword(chip->pci, 0x4c, &val); @@ -2424,10 +2443,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip) fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0); snd_dma_free_pages(&chip->bdbars); } - if (chip->addr) - pci_iounmap(chip->pci, chip->addr); - if (chip->bmaddr) - pci_iounmap(chip->pci, chip->bmaddr); + if (chip->remap_addr) + iounmap(chip->remap_addr); + if (chip->remap_bmaddr) + iounmap(chip->remap_bmaddr); pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); @@ -2501,7 +2520,7 @@ static int intel8x0_resume(struct pci_dev *pci) snd_intel8x0_chip_init(chip, 0); /* re-initialize mixer stuff */ - if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { + if (chip->device_type == DEVICE_INTEL_ICH4) { /* enable separate SDINs for ICH4 */ iputbyte(chip, ICHREG(SDM), chip->sdm_saved); /* use slot 10/11 for SPDIF */ @@ -2774,27 +2793,35 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, if (device_type == DEVICE_ALI) { /* ALI5455 has no ac97 region */ - chip->bmaddr = pci_iomap(pci, 0, 0); + chip->bmaddr = pci_resource_start(pci, 0); goto port_inited; } - if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */ - chip->addr = pci_iomap(pci, 2, 0); - else - chip->addr = pci_iomap(pci, 0, 0); - if (!chip->addr) { - snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); - snd_intel8x0_free(chip); - return -EIO; - } - if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */ - chip->bmaddr = pci_iomap(pci, 3, 0); - else - chip->bmaddr = pci_iomap(pci, 1, 0); - if (!chip->bmaddr) { - snd_printk(KERN_ERR "Controller space ioremap problem\n"); - snd_intel8x0_free(chip); - return -EIO; + if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */ + chip->mmio = 1; + chip->addr = pci_resource_start(pci, 2); + chip->remap_addr = ioremap_nocache(chip->addr, + pci_resource_len(pci, 2)); + if (chip->remap_addr == NULL) { + snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); + snd_intel8x0_free(chip); + return -EIO; + } + } else { + chip->addr = pci_resource_start(pci, 0); + } + if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */ + chip->bm_mmio = 1; + chip->bmaddr = pci_resource_start(pci, 3); + chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, + pci_resource_len(pci, 3)); + if (chip->remap_bmaddr == NULL) { + snd_printk(KERN_ERR "Controller space ioremap problem\n"); + snd_intel8x0_free(chip); + return -EIO; + } + } else { + chip->bmaddr = pci_resource_start(pci, 1); } port_inited: @@ -2937,29 +2964,6 @@ static struct shortname_table { { 0, NULL }, }; -static struct snd_pci_quirk spdif_aclink_defaults[] __devinitdata = { - SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1), - { } /* end */ -}; - -/* look up white/black list for SPDIF over ac-link */ -static int __devinit check_default_spdif_aclink(struct pci_dev *pci) -{ - const struct snd_pci_quirk *w; - - w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults); - if (w) { - if (w->value) - snd_printdd(KERN_INFO "intel8x0: Using SPDIF over " - "AC-Link for %s\n", w->name); - else - snd_printdd(KERN_INFO "intel8x0: Using integrated " - "SPDIF DMA for %s\n", w->name); - return w->value; - } - return 0; -} - static int __devinit snd_intel8x0_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -2972,18 +2976,16 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, if (card == NULL) return -ENOMEM; - if (spdif_aclink < 0) - spdif_aclink = check_default_spdif_aclink(pci); - - strcpy(card->driver, "ICH"); - if (!spdif_aclink) { - switch (pci_id->driver_data) { - case DEVICE_NFORCE: - strcpy(card->driver, "NFORCE"); - break; - case DEVICE_INTEL_ICH4: - strcpy(card->driver, "ICH4"); - } + switch (pci_id->driver_data) { + case DEVICE_NFORCE: + strcpy(card->driver, "NFORCE"); + break; + case DEVICE_INTEL_ICH4: + strcpy(card->driver, "ICH4"); + break; + default: + strcpy(card->driver, "ICH"); + break; } strcpy(card->shortname, "Intel ICH"); @@ -3023,8 +3025,8 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, snd_intel8x0_proc_init(chip); snprintf(card->longname, sizeof(card->longname), - "%s with %s at irq %i", card->shortname, - snd_ac97_get_short_name(chip->ac97[0]), chip->irq); + "%s with %s at %#lx, irq %i", card->shortname, + snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq); if (! ac97_clock) intel8x0_measure_ac97_clock(chip); diff --git a/trunk/sound/pci/intel8x0m.c b/trunk/sound/pci/intel8x0m.c index c155e1f3a0e5..09dcf923b547 100644 --- a/trunk/sound/pci/intel8x0m.c +++ b/trunk/sound/pci/intel8x0m.c @@ -196,8 +196,12 @@ struct intel8x0m { int irq; - void __iomem *addr; - void __iomem *bmaddr; + unsigned int mmio; + unsigned long addr; + void __iomem *remap_addr; + unsigned int bm_mmio; + unsigned long bmaddr; + void __iomem *remap_bmaddr; struct pci_dev *pci; struct snd_card *card; @@ -249,48 +253,72 @@ MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids); * Lowlevel I/O - busmaster */ -static inline u8 igetbyte(struct intel8x0m *chip, u32 offset) +static u8 igetbyte(struct intel8x0m *chip, u32 offset) { - return ioread8(chip->bmaddr + offset); + if (chip->bm_mmio) + return readb(chip->remap_bmaddr + offset); + else + return inb(chip->bmaddr + offset); } -static inline u16 igetword(struct intel8x0m *chip, u32 offset) +static u16 igetword(struct intel8x0m *chip, u32 offset) { - return ioread16(chip->bmaddr + offset); + if (chip->bm_mmio) + return readw(chip->remap_bmaddr + offset); + else + return inw(chip->bmaddr + offset); } -static inline u32 igetdword(struct intel8x0m *chip, u32 offset) +static u32 igetdword(struct intel8x0m *chip, u32 offset) { - return ioread32(chip->bmaddr + offset); + if (chip->bm_mmio) + return readl(chip->remap_bmaddr + offset); + else + return inl(chip->bmaddr + offset); } -static inline void iputbyte(struct intel8x0m *chip, u32 offset, u8 val) +static void iputbyte(struct intel8x0m *chip, u32 offset, u8 val) { - iowrite8(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writeb(val, chip->remap_bmaddr + offset); + else + outb(val, chip->bmaddr + offset); } -static inline void iputword(struct intel8x0m *chip, u32 offset, u16 val) +static void iputword(struct intel8x0m *chip, u32 offset, u16 val) { - iowrite16(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writew(val, chip->remap_bmaddr + offset); + else + outw(val, chip->bmaddr + offset); } -static inline void iputdword(struct intel8x0m *chip, u32 offset, u32 val) +static void iputdword(struct intel8x0m *chip, u32 offset, u32 val) { - iowrite32(val, chip->bmaddr + offset); + if (chip->bm_mmio) + writel(val, chip->remap_bmaddr + offset); + else + outl(val, chip->bmaddr + offset); } /* * Lowlevel I/O - AC'97 registers */ -static inline u16 iagetword(struct intel8x0m *chip, u32 offset) +static u16 iagetword(struct intel8x0m *chip, u32 offset) { - return ioread16(chip->addr + offset); + if (chip->mmio) + return readw(chip->remap_addr + offset); + else + return inw(chip->addr + offset); } -static inline void iaputword(struct intel8x0m *chip, u32 offset, u16 val) +static void iaputword(struct intel8x0m *chip, u32 offset, u16 val) { - iowrite16(val, chip->addr + offset); + if (chip->mmio) + writew(val, chip->remap_addr + offset); + else + outw(val, chip->addr + offset); } /* @@ -830,7 +858,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock) memset(&ac97, 0, sizeof(ac97)); ac97.private_data = chip; ac97.private_free = snd_intel8x0_mixer_free_ac97; - ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_AUDIO; glob_sta = igetdword(chip, ICHREG(GLOB_STA)); @@ -991,10 +1019,10 @@ static int snd_intel8x0_free(struct intel8x0m *chip) __hw_end: if (chip->bdbars.area) snd_dma_free_pages(&chip->bdbars); - if (chip->addr) - pci_iounmap(chip->pci, chip->addr); - if (chip->bmaddr) - pci_iounmap(chip->pci, chip->bmaddr); + if (chip->remap_addr) + iounmap(chip->remap_addr); + if (chip->remap_bmaddr) + iounmap(chip->remap_bmaddr); if (chip->irq >= 0) free_irq(chip->irq, chip); pci_release_regions(chip->pci); @@ -1145,27 +1173,35 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card, if (device_type == DEVICE_ALI) { /* ALI5455 has no ac97 region */ - chip->bmaddr = pci_iomap(pci, 0, 0); + chip->bmaddr = pci_resource_start(pci, 0); goto port_inited; } - if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */ - chip->addr = pci_iomap(pci, 2, 0); - else - chip->addr = pci_iomap(pci, 0, 0); - if (!chip->addr) { - snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); - snd_intel8x0_free(chip); - return -EIO; + if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */ + chip->mmio = 1; + chip->addr = pci_resource_start(pci, 2); + chip->remap_addr = ioremap_nocache(chip->addr, + pci_resource_len(pci, 2)); + if (chip->remap_addr == NULL) { + snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); + snd_intel8x0_free(chip); + return -EIO; + } + } else { + chip->addr = pci_resource_start(pci, 0); } - if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */ - chip->bmaddr = pci_iomap(pci, 3, 0); - else - chip->bmaddr = pci_iomap(pci, 1, 0); - if (!chip->bmaddr) { - snd_printk(KERN_ERR "Controller space ioremap problem\n"); - snd_intel8x0_free(chip); - return -EIO; + if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */ + chip->bm_mmio = 1; + chip->bmaddr = pci_resource_start(pci, 3); + chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, + pci_resource_len(pci, 3)); + if (chip->remap_bmaddr == NULL) { + snd_printk(KERN_ERR "Controller space ioremap problem\n"); + snd_intel8x0_free(chip); + return -EIO; + } + } else { + chip->bmaddr = pci_resource_start(pci, 1); } port_inited: @@ -1303,8 +1339,8 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, snd_intel8x0m_proc_init(chip); - sprintf(card->longname, "%s at irq %i", - card->shortname, chip->irq); + sprintf(card->longname, "%s at 0x%lx, irq %i", + card->shortname, chip->addr, chip->irq); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/korg1212/korg1212.c b/trunk/sound/pci/korg1212/korg1212.c index 21d0899ac382..345eefeedb39 100644 --- a/trunk/sound/pci/korg1212/korg1212.c +++ b/trunk/sound/pci/korg1212/korg1212.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -264,15 +263,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 #include "korg1212-firmware.h" -static const struct firmware static_dsp_code = { - .data = (u8 *)dspCode, - .size = sizeof dspCode -}; -#endif enum ClockSourceIndex { K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz @@ -354,6 +345,8 @@ struct snd_korg1212 { struct snd_dma_buffer dma_rec; struct snd_dma_buffer dma_shared; + u32 dspCodeSize; + u32 DataBufsSize; struct KorgAudioBuffer * playDataBufsPtr; @@ -1230,6 +1223,8 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212) snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS); + memcpy(korg1212->dma_dsp.area, dspCode, korg1212->dspCodeSize); + rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload, UpperWordSwap(korg1212->dma_dsp.addr), 0, 0, 0); @@ -2161,7 +2156,6 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * unsigned int i; unsigned ioport_size, iomem_size, iomem2_size; struct snd_korg1212 * korg1212; - const struct firmware *dsp_code; static struct snd_device_ops ops = { .dev_free = snd_korg1212_dev_free, @@ -2335,6 +2329,8 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * #endif // K1212_LARGEALLOC + korg1212->dspCodeSize = sizeof (dspCode); + korg1212->VolumeTablePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, volumeData); korg1212->RoutingTablePhy = korg1212->sharedBufferPhy + @@ -2342,40 +2338,17 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, AdatTimeCode); - 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 - } - 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); + korg1212->dspCodeSize, &korg1212->dma_dsp) < 0) { + snd_printk(KERN_ERR "korg1212: can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize); snd_korg1212_free(korg1212); -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) -#endif - release_firmware(dsp_code); return -ENOMEM; } K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n", - korg1212->dma_dsp.area, korg1212->dma_dsp.addr, dsp_code->size, + korg1212->dma_dsp.area, korg1212->dma_dsp.addr, korg1212->dspCodeSize, stateName[korg1212->cardState]); - memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); - -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) -#endif - release_firmware(dsp_code); - rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); if (rc) diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 4526904e3f86..6efe6d5ade1e 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -49,7 +48,6 @@ #include #include #include -#include MODULE_AUTHOR("Zach Brown , Takashi Iwai "); MODULE_DESCRIPTION("ESS Maestro3 PCI"); @@ -770,6 +768,21 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)"); /* */ +/* quirk lists */ +struct m3_quirk { + const char *name; /* device name */ + u16 vendor, device; /* subsystem ids */ + int amp_gpio; /* gpio pin # for external amp, -1 = default */ + int irda_workaround; /* non-zero if avoid to touch 0x10 on GPIO_DIRECTION + (e.g. for IrDA on Dell Inspirons) */ +}; + +struct m3_hv_quirk { + u16 vendor, device, subsystem_vendor, subsystem_device; + u32 config; /* ALLEGRO_CONFIG hardware volume bits */ + int is_omnibook; /* Do HP OmniBook GPIO magic? */ +}; + struct m3_list { int curlen; int mem_addr; @@ -817,6 +830,8 @@ struct snd_m3 { struct snd_pcm *pcm; struct pci_dev *pci; + const struct m3_quirk *quirk; + const struct m3_hv_quirk *hv_quirk; int dacs_active; int timer_users; @@ -830,11 +845,7 @@ struct snd_m3 { u8 reset_state; int external_amp; - int amp_gpio; /* gpio pin # for external amp, -1 = default */ - unsigned int hv_config; /* hardware-volume config bits */ - unsigned irda_workaround :1; /* avoid to touch 0x10 on GPIO_DIRECTION - (e.g. for IrDA on Dell Inspirons) */ - unsigned is_omnibook :1; /* Do HP OmniBook GPIO magic? */ + int amp_gpio; /* midi */ struct snd_rawmidi *rmidi; @@ -853,9 +864,6 @@ struct snd_m3 { #ifdef CONFIG_PM u16 *suspend_mem; #endif - - const struct firmware *assp_kernel_image; - const struct firmware *assp_minisrc_image; }; /* @@ -883,104 +891,127 @@ static struct pci_device_id snd_m3_ids[] = { MODULE_DEVICE_TABLE(pci, snd_m3_ids); -static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { - SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), - SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), - SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), - SND_PCI_QUIRK(0x1509, 0x1740, "LEGEND ZhaoYang 3100CF", 0x03), - { } /* END */ +static const struct m3_quirk m3_quirk_list[] = { + /* panasonic CF-28 "toughbook" */ + { + .name = "Panasonic CF-28", + .vendor = 0x10f7, + .device = 0x833e, + .amp_gpio = 0x0d, + }, + /* panasonic CF-72 "toughbook" */ + { + .name = "Panasonic CF-72", + .vendor = 0x10f7, + .device = 0x833d, + .amp_gpio = 0x0d, + }, + /* Dell Inspiron 4000 */ + { + .name = "Dell Inspiron 4000", + .vendor = 0x1028, + .device = 0x00b0, + .amp_gpio = -1, + .irda_workaround = 1, + }, + /* Dell Inspiron 8000 */ + { + .name = "Dell Inspiron 8000", + .vendor = 0x1028, + .device = 0x00a4, + .amp_gpio = -1, + .irda_workaround = 1, + }, + /* Dell Inspiron 8100 */ + { + .name = "Dell Inspiron 8100", + .vendor = 0x1028, + .device = 0x00e6, + .amp_gpio = -1, + .irda_workaround = 1, + }, + /* NEC LM800J/7 */ + { + .name = "NEC LM800J/7", + .vendor = 0x1033, + .device = 0x80f1, + .amp_gpio = 0x03, + }, + /* LEGEND ZhaoYang 3100CF */ + { + .name = "LEGEND ZhaoYang 3100CF", + .vendor = 0x1509, + .device = 0x1740, + .amp_gpio = 0x03, + }, + /* END */ + { NULL } }; -static struct snd_pci_quirk m3_irda_quirk_list[] __devinitdata = { - SND_PCI_QUIRK(0x1028, 0x00b0, "Dell Inspiron 4000", 1), - SND_PCI_QUIRK(0x1028, 0x00a4, "Dell Inspiron 8000", 1), - SND_PCI_QUIRK(0x1028, 0x00e6, "Dell Inspiron 8100", 1), - { } /* END */ -}; - -/* hardware volume quirks */ -static struct snd_pci_quirk m3_hv_quirk_list[] __devinitdata = { +/* These values came from the Windows driver. */ +static const struct m3_hv_quirk m3_hv_quirk_list[] = { /* Allegro chips */ - SND_PCI_QUIRK(0x0E11, 0x002E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x0E11, 0x0094, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x0E11, 0xB112, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x0E11, 0xB114, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x103C, 0x0012, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x103C, 0x0018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x103C, 0x001C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x103C, 0x001D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x103C, 0x001E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x107B, 0x3350, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x10F7, 0x8338, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x10F7, 0x833C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x10F7, 0x833D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x10F7, 0x833E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x10F7, 0x833F, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x13BD, 0x1018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x13BD, 0x1019, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x13BD, 0x101A, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x14FF, 0x0F03, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x14FF, 0x0F04, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x14FF, 0x0F05, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x156D, 0xB400, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x156D, 0xB795, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x156D, 0xB797, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x156D, 0xC700, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD), - SND_PCI_QUIRK(0x1033, 0x80F1, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x103C, 0x001A, NULL, /* HP OmniBook 6100 */ - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x107B, 0x340A, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x107B, 0x3450, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x109F, 0x3134, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x109F, 0x3161, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0x3280, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0x3281, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0xC002, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0xC003, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x1509, 0x1740, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x1610, 0x0010, NULL, - HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x1042, 0x1042, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x107B, 0x9500, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x14FF, 0x0F06, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x1558, 0x8586, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x161F, 0x2011, NULL, HV_CTRL_ENABLE), + { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x0E11, 0xB112, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x0E11, 0xB114, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x103C, 0x0012, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x103C, 0x0018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x103C, 0x001C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x103C, 0x001D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x103C, 0x001E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x107B, 0x3350, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x10F7, 0x8338, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x10F7, 0x833C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x10F7, 0x833D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x10F7, 0x833E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x10F7, 0x833F, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x13BD, 0x1018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x13BD, 0x1019, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x13BD, 0x101A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x14FF, 0x0F03, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x14FF, 0x0F04, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x14FF, 0x0F05, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x156D, 0xB400, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x156D, 0xB795, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x156D, 0xB797, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x156D, 0xC700, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, + { 0x125D, 0x1988, 0x1033, 0x80F1, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x103C, 0x001A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, /* HP OmniBook 6100 */ + { 0x125D, 0x1988, 0x107B, 0x340A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x107B, 0x3450, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x109F, 0x3134, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x109F, 0x3161, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x144D, 0x3280, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x144D, 0x3281, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x144D, 0xC002, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x144D, 0xC003, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x1509, 0x1740, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x1610, 0x0010, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x1988, 0x1042, 0x1042, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1988, 0x107B, 0x9500, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1988, 0x14FF, 0x0F06, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1988, 0x1558, 0x8586, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1988, 0x161F, 0x2011, HV_CTRL_ENABLE, 0 }, /* Maestro3 chips */ - SND_PCI_QUIRK(0x103C, 0x000E, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x103C, 0x0010, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x103C, 0x0011, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x103C, 0x001B, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x104D, 0x80A6, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x104D, 0x80AA, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x107B, 0x5300, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x110A, 0x1998, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x13BD, 0x1015, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x13BD, 0x101C, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x13BD, 0x1802, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x1599, 0x0715, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x5643, 0x5643, NULL, HV_CTRL_ENABLE), - SND_PCI_QUIRK(0x144D, 0x3260, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0x3261, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0xC000, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE), - SND_PCI_QUIRK(0x144D, 0xC001, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE), - { } /* END */ -}; - -/* HP Omnibook quirks */ -static struct snd_pci_quirk m3_omnibook_quirk_list[] __devinitdata = { - SND_PCI_QUIRK_ID(0x103c, 0x0010), /* HP OmniBook 6000 */ - SND_PCI_QUIRK_ID(0x103c, 0x0011), /* HP OmniBook 500 */ - { } /* END */ + { 0x125D, 0x1998, 0x103C, 0x000E, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x103C, 0x0010, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 6000 */ + { 0x125D, 0x1998, 0x103C, 0x0011, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 500 */ + { 0x125D, 0x1998, 0x103C, 0x001B, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x104D, 0x80A6, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x104D, 0x80AA, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x107B, 0x5300, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x110A, 0x1998, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x13BD, 0x1015, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x13BD, 0x101C, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x13BD, 0x1802, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x1599, 0x0715, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x1998, 0x5643, 0x5643, HV_CTRL_ENABLE, 0 }, + { 0x125D, 0x199A, 0x144D, 0x3260, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x199A, 0x144D, 0x3261, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x199A, 0x144D, 0xC000, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, + { 0x125D, 0x199A, 0x144D, 0xC001, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, + { 0 } }; /* @@ -2019,7 +2050,7 @@ static void snd_m3_ac97_reset(struct snd_m3 *chip) for (i = 0; i < 5; i++) { dir = inw(io + GPIO_DIRECTION); - if (!chip->irda_workaround) + if (! chip->quirk || ! chip->quirk->irda_workaround) dir |= 0x10; /* assuming pci bus master? */ snd_m3_remote_codec_config(io, 0); @@ -2101,10 +2132,6 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL - /* * DSP Code images */ @@ -2233,30 +2260,6 @@ static const u16 assp_minisrc_image[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; -static const struct firmware assp_kernel = { - .data = (u8 *)assp_kernel_image, - .size = sizeof assp_kernel_image -}; -static const struct firmware assp_minisrc = { - .data = (u8 *)assp_minisrc_image, - .size = sizeof assp_minisrc_image -}; - -#endif /* FIRMWARE_IN_THE_KERNEL */ - -#ifdef __LITTLE_ENDIAN -static inline void snd_m3_convert_from_le(const struct firmware *fw) { } -#else -static void snd_m3_convert_from_le(const struct firmware *fw) -{ - int i; - u16 *data = (u16 *)fw->data; - - for (i = 0; i < fw->size / 2; ++i) - le16_to_cpus(&data[i]); -} -#endif - /* * initialize ASSP @@ -2271,7 +2274,6 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = { static void snd_m3_assp_init(struct snd_m3 *chip) { unsigned int i; - u16 *data; /* zero kernel data */ for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) @@ -2289,10 +2291,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip) KDATA_DMA_XFER0); /* write kernel into code memory.. */ - data = (u16 *)chip->assp_kernel_image->data; - for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) { + for (i = 0 ; i < ARRAY_SIZE(assp_kernel_image); i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, - REV_B_CODE_MEMORY_BEGIN + i, data[i]); + REV_B_CODE_MEMORY_BEGIN + i, + assp_kernel_image[i]); } /* @@ -2301,10 +2303,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip) * drop it there. It seems that the minisrc doesn't * need vectors, so we won't bother with them.. */ - data = (u16 *)chip->assp_minisrc_image->data; - for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) { + for (i = 0; i < ARRAY_SIZE(assp_minisrc_image); i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, - 0x400 + i, data[i]); + 0x400 + i, + assp_minisrc_image[i]); } /* @@ -2442,7 +2444,7 @@ snd_m3_chip_init(struct snd_m3 *chip) DISABLE_LEGACY); pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w); - if (chip->is_omnibook) { + if (chip->hv_quirk && chip->hv_quirk->is_omnibook) { /* * Volume buttons on some HP OmniBook laptops don't work * correctly. This makes them work for the most part. @@ -2459,7 +2461,8 @@ snd_m3_chip_init(struct snd_m3 *chip) } pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD); - n |= chip->hv_config; + if (chip->hv_quirk) + n |= chip->hv_quirk->config; /* For some reason we must always use reduced debounce. */ n |= REDUCED_DEBOUNCE; n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING; @@ -2507,7 +2510,7 @@ snd_m3_enable_ints(struct snd_m3 *chip) /* TODO: MPU401 not supported yet */ val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; - if (chip->hv_config & HV_CTRL_ENABLE) + if (chip->hv_quirk && (chip->hv_quirk->config & HV_CTRL_ENABLE)) val |= HV_INT_ENABLE; outw(val, io + HOST_INT_CTRL); outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, @@ -2550,15 +2553,6 @@ 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) -#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); return 0; @@ -2671,7 +2665,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, { struct snd_m3 *chip; int i, err; - const struct snd_pci_quirk *quirk; + const struct m3_quirk *quirk; + const struct m3_hv_quirk *hv_quirk; static struct snd_device_ops ops = { .dev_free = snd_m3_dev_free, }; @@ -2711,32 +2706,34 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, chip->pci = pci; chip->irq = -1; - chip->external_amp = enable_amp; - if (amp_gpio >= 0 && amp_gpio <= 0x0f) - chip->amp_gpio = amp_gpio; - else { - quirk = snd_pci_quirk_lookup(pci, m3_amp_quirk_list); - if (quirk) { - snd_printdd(KERN_INFO "maestro3: set amp-gpio " - "for '%s'\n", quirk->name); - chip->amp_gpio = quirk->value; - } else if (chip->allegro_flag) - chip->amp_gpio = GPO_EXT_AMP_ALLEGRO; - else /* presumably this is for all 'maestro3's.. */ - chip->amp_gpio = GPO_EXT_AMP_M3; + for (quirk = m3_quirk_list; quirk->vendor; quirk++) { + if (pci->subsystem_vendor == quirk->vendor && + pci->subsystem_device == quirk->device) { + printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name); + chip->quirk = quirk; + break; + } } - quirk = snd_pci_quirk_lookup(pci, m3_irda_quirk_list); - if (quirk) { - snd_printdd(KERN_INFO "maestro3: enabled irda workaround " - "for '%s'\n", quirk->name); - chip->irda_workaround = 1; + for (hv_quirk = m3_hv_quirk_list; hv_quirk->vendor; hv_quirk++) { + if (pci->vendor == hv_quirk->vendor && + pci->device == hv_quirk->device && + pci->subsystem_vendor == hv_quirk->subsystem_vendor && + pci->subsystem_device == hv_quirk->subsystem_device) { + chip->hv_quirk = hv_quirk; + break; + } } - quirk = snd_pci_quirk_lookup(pci, m3_hv_quirk_list); - if (quirk) - chip->hv_config = quirk->value; - if (snd_pci_quirk_lookup(pci, m3_omnibook_quirk_list)) - chip->is_omnibook = 1; + + chip->external_amp = enable_amp; + if (amp_gpio >= 0 && amp_gpio <= 0x0f) + chip->amp_gpio = amp_gpio; + else if (chip->quirk && chip->quirk->amp_gpio >= 0) + chip->amp_gpio = chip->quirk->amp_gpio; + else if (chip->allegro_flag) + chip->amp_gpio = GPO_EXT_AMP_ALLEGRO; + else /* presumably this is for all 'maestro3's.. */ + chip->amp_gpio = GPO_EXT_AMP_M3; chip->num_substreams = NR_DSPS; chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma), @@ -2747,30 +2744,6 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -ENOMEM; } - 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); - - 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); - if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); return err; diff --git a/trunk/sound/pci/mixart/mixart_mixer.c b/trunk/sound/pci/mixart/mixart_mixer.c index d7d15c036e02..13de0f71d4b7 100644 --- a/trunk/sound/pci/mixart/mixart_mixer.c +++ b/trunk/sound/pci/mixart/mixart_mixer.c @@ -389,7 +389,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e return changed; } -static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); static struct snd_kcontrol_new mixart_control_analog_level = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -872,7 +872,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return changed; } -static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); static struct snd_kcontrol_new snd_mixart_pcm_vol = { diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index 03b3a4792f73..879e31a9f9c6 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -1628,15 +1628,23 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, } +struct nm256_quirk { + unsigned short vendor; + unsigned short device; + int type; +}; + enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 }; -static struct snd_pci_quirk nm256_quirks[] __devinitdata = { +static struct nm256_quirk nm256_quirks[] __devinitdata = { /* HP omnibook 4150 has cs4232 codec internally */ - SND_PCI_QUIRK(0x103c, 0x0007, "HP omnibook 4150", NM_BLACKLISTED), - /* Reset workarounds to avoid lock-ups */ - SND_PCI_QUIRK(0x104d, 0x8041, "Sony PCG-F305", NM_RESET_WORKAROUND), - SND_PCI_QUIRK(0x1028, 0x0080, "Dell Latitude LS", NM_RESET_WORKAROUND), - SND_PCI_QUIRK(0x1028, 0x0091, "Dell Latitude CSx", NM_RESET_WORKAROUND_2), + { .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED }, + /* Sony PCG-F305 */ + { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND }, + /* Dell Latitude LS */ + { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND }, + /* Dell Latitude CSx */ + { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 }, { } /* terminator */ }; @@ -1647,22 +1655,26 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci, struct snd_card *card; struct nm256 *chip; int err; - const struct snd_pci_quirk *q; - - q = snd_pci_quirk_lookup(pci, nm256_quirks); - if (q) { - snd_printdd(KERN_INFO "nm256: Enabled quirk for %s.\n", q->name); - switch (q->value) { - case NM_BLACKLISTED: - printk(KERN_INFO "nm256: The device is blacklisted. " - "Loading stopped\n"); - return -ENODEV; - case NM_RESET_WORKAROUND_2: - reset_workaround_2 = 1; - /* Fall-through */ - case NM_RESET_WORKAROUND: - reset_workaround = 1; - break; + struct nm256_quirk *q; + u16 subsystem_vendor, subsystem_device; + + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); + + for (q = nm256_quirks; q->vendor; q++) { + if (q->vendor == subsystem_vendor && q->device == subsystem_device) { + switch (q->type) { + case NM_BLACKLISTED: + printk(KERN_INFO "nm256: The device is blacklisted. " + "Loading stopped\n"); + return -ENODEV; + case NM_RESET_WORKAROUND_2: + reset_workaround_2 = 1; + /* Fall-through */ + case NM_RESET_WORKAROUND: + reset_workaround = 1; + break; + } } } diff --git a/trunk/sound/pci/pcxhr/pcxhr_mixer.c b/trunk/sound/pci/pcxhr/pcxhr_mixer.c index d9cc8d2beb6d..b133ad9e095e 100644 --- a/trunk/sound/pci/pcxhr/pcxhr_mixer.c +++ b/trunk/sound/pci/pcxhr/pcxhr_mixer.c @@ -44,8 +44,8 @@ #define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */ #define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */ -static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); +static DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) { @@ -195,7 +195,7 @@ static struct snd_kcontrol_new pcxhr_control_output_switch = { #define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */ #define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */ -static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); #define MORE_THAN_ONE_STREAM_LEVEL 0x000001 #define VALID_STREAM_PAN_LEVEL_MASK 0x800000 diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index 89b3c7ff5037..6383987b460e 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -80,7 +80,6 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," /* Write registers. These are defined as byte-offsets from the iobase value. */ #define HDSP_resetPointer 0 -#define HDSP_freqReg 0 #define HDSP_outputBufferAddress 32 #define HDSP_inputBufferAddress 36 #define HDSP_controlRegister 64 @@ -470,7 +469,6 @@ struct hdsp { struct pci_dev *pci; struct snd_kcontrol *spdif_ctl; unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE]; - unsigned int dds_value; /* last value written to freq register */ }; /* These tables map the ALSA channels 1..N to the channels that we @@ -600,7 +598,6 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out) return (64 * out) + (32 + (in)); case 0x96: case 0x97: - case 0x98: return (32 * out) + (16 + (in)); default: return (52 * out) + (26 + (in)); @@ -614,7 +611,6 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out) return (64 * out) + in; case 0x96: case 0x97: - case 0x98: return (32 * out) + in; default: return (52 * out) + in; @@ -942,11 +938,6 @@ static snd_pcm_uframes_t hdsp_hw_pointer(struct hdsp *hdsp) static void hdsp_reset_hw_pointer(struct hdsp *hdsp) { hdsp_write (hdsp, HDSP_resetPointer, 0); - if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152) - /* HDSP_resetPointer = HDSP_freqReg, which is strange and - * requires (?) to write again DDS value after a reset pointer - * (at least, it works like this) */ - hdsp_write (hdsp, HDSP_freqReg, hdsp->dds_value); } static void hdsp_start_audio(struct hdsp *s) @@ -991,30 +982,6 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames) return 0; } -static void hdsp_set_dds_value(struct hdsp *hdsp, 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 */ - div64_32(&n, rate, &r); - /* n should be less than 2^32 for being written to FREQ register */ - snd_assert((n >> 32) == 0); - /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS - value to write it after a reset */ - hdsp->dds_value = n; - hdsp_write(hdsp, HDSP_freqReg, hdsp->dds_value); -} - static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) { int reject_if_open = 0; @@ -1123,10 +1090,6 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) hdsp->control_register |= rate_bits; hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - /* For HDSP9632 rev 152, need to set DDS value in FREQ register */ - if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152) - hdsp_set_dds_value(hdsp, rate); - if (rate >= 128000) { hdsp->channel_map = channel_map_H9632_qs; } else if (rate > 48000) { @@ -4980,7 +4943,6 @@ static int __devinit snd_hdsp_create(struct snd_card *card, hdsp->irq = pci->irq; hdsp->precise_ptr = 0; hdsp->use_midi_tasklet = 1; - hdsp->dds_value = 0; if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) return err; diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index e0215aca1193..0547f6f04bdc 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -6,8 +6,6 @@ * code based on hdsp.c Paul Davis * Marcus Andersson * Thomas Charbonnel - * Modified 2006-06-01 for AES32 support by Remy Bruno - * * * 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 @@ -79,8 +77,7 @@ MODULE_PARM_DESC(enable_monitor, MODULE_AUTHOR ("Winfried Ritsch , Paul Davis , " - "Marcus Andersson, Thomas Charbonnel , " - "Remy Bruno "); + "Marcus Andersson, Thomas Charbonnel "); MODULE_DESCRIPTION("RME HDSPM"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); @@ -110,12 +107,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); /* --- Read registers. --- These are defined as byte-offsets from the iobase value */ #define HDSPM_statusRegister 0 -/*#define HDSPM_statusRegister2 96 */ -/* after RME Windows driver sources, status2 is 4-byte word # 48 = word at - * offset 192, for AES32 *and* MADI - * => need to check that offset 192 is working on MADI */ -#define HDSPM_statusRegister2 192 -#define HDSPM_timecodeRegister 128 +#define HDSPM_statusRegister2 96 #define HDSPM_midiDataIn0 360 #define HDSPM_midiDataIn1 364 @@ -148,50 +140,37 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */ #define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */ #define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */ -#define HDSPM_QuadSpeed (1<<31) /* quad speed bit */ +#define HDSPM_QuadSpeed (1<<31) /* quad speed bit, not implemented now */ -#define HDSPM_Professional (1<<9) /* Professional */ /* AES32 ONLY */ #define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1, - 56channelMODE=0 */ /* MADI ONLY*/ -#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */ + 56channelMODE=0 */ #define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, - 0=off, 1=on */ /* MADI ONLY */ -#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */ + 0=off, 1=on */ -#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ /* MADI ONLY*/ +#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ #define HDSPM_InputSelect1 (1<<15) /* should be 0 */ #define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */ -#define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */ -#define HDSPM_SyncRef2 (1<<13) -#define HDSPM_SyncRef3 (1<<25) +#define HDSPM_SyncRef1 (1<<17) /* should be 0 */ -#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */ #define HDSPM_clr_tms (1<<19) /* clear track marker, do not use AES additional bits in lower 5 Audiodatabits ??? */ -#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */ -#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */ #define HDSPM_Midi0InterruptEnable (1<<22) #define HDSPM_Midi1InterruptEnable (1<<23) #define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ -#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */ -#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */ -#define HDSPM_QS_QuadWire (1<<28) /* AES32 ONLY */ - -#define HDSPM_wclk_sel (1<<30) /* --- bit helper defines */ #define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) -#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|HDSPM_DoubleSpeed|HDSPM_QuadSpeed) +#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1) #define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1) #define HDSPM_InputOptical 0 #define HDSPM_InputCoaxial (HDSPM_InputSelect0) -#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|HDSPM_SyncRef2|HDSPM_SyncRef3) +#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1) #define HDSPM_SyncRef_Word 0 #define HDSPM_SyncRef_MADI (HDSPM_SyncRef0) @@ -204,9 +183,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0) #define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1) #define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0) -#define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0) -#define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1) -#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|HDSPM_Frequency0) /* --- for internal discrimination */ #define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */ @@ -253,8 +229,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_BIGENDIAN_MODE (1<<9) #define HDSPM_RD_MULTIPLE (1<<10) -/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and - that do not conflict with specific bits for AES32 seem to be valid also for the AES32 */ +/* --- Status Register bits --- */ #define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */ #define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */ #define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */ @@ -288,7 +263,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_madiFreq176_4 (HDSPM_madiFreq3) #define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0) -/* Status2 Register bits */ /* MADI ONLY */ +/* Status2 Register bits */ #define HDSPM_version0 (1<<0) /* not realy defined but I guess */ #define HDSPM_version1 (1<<1) /* in former cards it was ??? */ @@ -322,56 +297,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) #define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2) -/* - For AES32, bits for status, status2 and timecode are different -*/ -/* status */ -#define HDSPM_AES32_wcLock 0x0200000 -#define HDSPM_AES32_wcFreq_bit 22 -/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function - HDSPM_bit2freq */ -#define HDSPM_AES32_syncref_bit 16 -/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */ - -#define HDSPM_AES32_AUTOSYNC_FROM_WORD 0 -#define HDSPM_AES32_AUTOSYNC_FROM_AES1 1 -#define HDSPM_AES32_AUTOSYNC_FROM_AES2 2 -#define HDSPM_AES32_AUTOSYNC_FROM_AES3 3 -#define HDSPM_AES32_AUTOSYNC_FROM_AES4 4 -#define HDSPM_AES32_AUTOSYNC_FROM_AES5 5 -#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 -#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 -#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 -#define HDSPM_AES32_AUTOSYNC_FROM_NONE -1 - -/* status2 */ -/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ -#define HDSPM_LockAES 0x80 -#define HDSPM_LockAES1 0x80 -#define HDSPM_LockAES2 0x40 -#define HDSPM_LockAES3 0x20 -#define HDSPM_LockAES4 0x10 -#define HDSPM_LockAES5 0x8 -#define HDSPM_LockAES6 0x4 -#define HDSPM_LockAES7 0x2 -#define HDSPM_LockAES8 0x1 -/* - Timecode - After windows driver sources, bits 4*i to 4*i+3 give the input frequency on - AES i+1 - bits 3210 - 0001 32kHz - 0010 44.1kHz - 0011 48kHz - 0100 64kHz - 0101 88.2kHz - 0110 96kHz - 0111 128kHz - 1000 176.4kHz - 1001 192kHz - NB: Timecode register doesn't seem to work on AES32 card revision 230 -*/ - /* Mixer Values */ #define UNITY_GAIN 32768 /* = 65536/2 */ #define MINUS_INFINITY_GAIN 0 @@ -389,14 +314,10 @@ 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 */ -#define HDSPM_AESREVISION 230 - struct hdspm_midi { struct hdspm *hdspm; int id; @@ -415,9 +336,7 @@ struct hdspm { struct snd_pcm_substream *playback_substream; /* and/or capture stream */ char *card_name; /* for procinfo */ - unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/ - - unsigned char is_aes32; /* indicates if card is AES32 */ + unsigned short firmware_rev; /* dont know if relevant */ int precise_ptr; /* use precise pointers, to be tested */ int monitor_outs; /* set up monitoring outs init flag */ @@ -534,15 +453,6 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm); static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, unsigned int reg, int channels); -static inline int HDSPM_bit2freq(int n) -{ - static int bit2freq_tab[] = { 0, 32000, 44100, 48000, 64000, 88200, - 96000, 128000, 176400, 192000 }; - if (n < 1 || n > 9) - return 0; - return bit2freq_tab[n]; -} - /* Write/read to/from HDSPM with Adresses in Bytes not words but only 32Bit writes are allowed */ @@ -634,105 +544,86 @@ static inline int snd_hdspm_use_is_exclusive(struct hdspm * hdspm) /* check for external sample rate */ static inline int hdspm_external_sample_rate(struct hdspm * hdspm) { - if (hdspm->is_aes32) { - unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); - unsigned int timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); - - int syncref = hdspm_autosync_ref(hdspm); - - if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && - status & HDSPM_AES32_wcLock) - return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); - if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && - syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && - status2 & (HDSPM_LockAES >> - (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) - return HDSPM_bit2freq((timecode >> - (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); - return 0; - } else { - unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); - unsigned int rate_bits; - int rate = 0; + unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); + unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); + unsigned int rate_bits; + int rate = 0; - /* if wordclock has synced freq and wordclock is valid */ - if ((status2 & HDSPM_wcLock) != 0 && - (status & HDSPM_SelSyncRef0) == 0) { + /* if wordclock has synced freq and wordclock is valid */ + if ((status2 & HDSPM_wcLock) != 0 && + (status & HDSPM_SelSyncRef0) == 0) { - rate_bits = status2 & HDSPM_wcFreqMask; + rate_bits = status2 & HDSPM_wcFreqMask; - switch (rate_bits) { - case HDSPM_wcFreq32: - rate = 32000; - break; - case HDSPM_wcFreq44_1: - rate = 44100; - break; - case HDSPM_wcFreq48: - rate = 48000; - break; - case HDSPM_wcFreq64: - rate = 64000; - break; - case HDSPM_wcFreq88_2: - rate = 88200; - break; - case HDSPM_wcFreq96: - rate = 96000; - break; - /* Quadspeed Bit missing ???? */ - default: - rate = 0; - break; - } + switch (rate_bits) { + case HDSPM_wcFreq32: + rate = 32000; + break; + case HDSPM_wcFreq44_1: + rate = 44100; + break; + case HDSPM_wcFreq48: + rate = 48000; + break; + case HDSPM_wcFreq64: + rate = 64000; + break; + case HDSPM_wcFreq88_2: + rate = 88200; + break; + case HDSPM_wcFreq96: + rate = 96000; + break; + /* Quadspeed Bit missing ???? */ + default: + rate = 0; + break; } + } - /* if rate detected and Syncref is Word than have it, word has priority to MADI */ - if (rate != 0 && - (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) - return rate; + /* if rate detected and Syncref is Word than have it, word has priority to MADI */ + if (rate != 0 + && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) + return rate; - /* maby a madi input (which is taken if sel sync is madi) */ - if (status & HDSPM_madiLock) { - rate_bits = status & HDSPM_madiFreqMask; + /* maby a madi input (which is taken if sel sync is madi) */ + if (status & HDSPM_madiLock) { + rate_bits = status & HDSPM_madiFreqMask; - switch (rate_bits) { - case HDSPM_madiFreq32: - rate = 32000; - break; - case HDSPM_madiFreq44_1: - rate = 44100; - break; - case HDSPM_madiFreq48: - rate = 48000; - break; - case HDSPM_madiFreq64: - rate = 64000; - break; - case HDSPM_madiFreq88_2: - rate = 88200; - break; - case HDSPM_madiFreq96: - rate = 96000; - break; - case HDSPM_madiFreq128: - rate = 128000; - break; - case HDSPM_madiFreq176_4: - rate = 176400; - break; - case HDSPM_madiFreq192: - rate = 192000; - break; - default: - rate = 0; - break; - } + switch (rate_bits) { + case HDSPM_madiFreq32: + rate = 32000; + break; + case HDSPM_madiFreq44_1: + rate = 44100; + break; + case HDSPM_madiFreq48: + rate = 48000; + break; + case HDSPM_madiFreq64: + rate = 64000; + break; + case HDSPM_madiFreq88_2: + rate = 88200; + break; + case HDSPM_madiFreq96: + rate = 96000; + break; + case HDSPM_madiFreq128: + rate = 128000; + break; + case HDSPM_madiFreq176_4: + rate = 176400; + break; + case HDSPM_madiFreq192: + rate = 192000; + break; + default: + rate = 0; + break; } - return rate; } + return rate; } /* Latency function */ @@ -785,8 +676,7 @@ static inline void hdspm_silence_playback(struct hdspm * hdspm) int n = hdspm->period_bytes; void *buf = hdspm->playback_buffer; - if (buf == NULL) - return; + snd_assert(buf != NULL, return); for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { memset(buf, 0, n); @@ -826,7 +716,6 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) int current_rate; int rate_bits; int not_set = 0; - int is_single, is_double, is_quad; /* ASSUMPTION: hdspm->lock is either set, or there is no need for it (e.g. during module initialization). @@ -877,56 +766,43 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) changes in the read/write routines. */ - is_single = (current_rate <= 48000); - is_double = (current_rate > 48000 && current_rate <= 96000); - is_quad = (current_rate > 96000); - switch (rate) { case 32000: - if (!is_single) + if (current_rate > 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency32KHz; break; case 44100: - if (!is_single) + if (current_rate > 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency44_1KHz; break; case 48000: - if (!is_single) + if (current_rate > 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency48KHz; break; case 64000: - if (!is_double) + if (current_rate <= 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency64KHz; break; case 88200: - if (!is_double) + if (current_rate <= 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency88_2KHz; break; case 96000: - if (!is_double) + if (current_rate <= 48000) { reject_if_open = 1; + } rate_bits = HDSPM_Frequency96KHz; break; - case 128000: - if (!is_quad) - reject_if_open = 1; - rate_bits = HDSPM_Frequency128KHz; - break; - case 176400: - if (!is_quad) - reject_if_open = 1; - rate_bits = HDSPM_Frequency176_4KHz; - break; - case 192000: - if (!is_quad) - reject_if_open = 1; - rate_bits = HDSPM_Frequency192KHz; - break; default: return -EINVAL; } @@ -943,7 +819,7 @@ 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*/) + if (rate > 64000) hdspm->channel_map = channel_map_madi_qs; else if (rate > 48000) hdspm->channel_map = channel_map_madi_ds; @@ -1579,27 +1455,11 @@ static int hdspm_pref_sync_ref(struct hdspm * hdspm) /* Notice that this looks at the requested sync source, not the one actually in use. */ - if (hdspm->is_aes32) { - switch (hdspm->control_register & HDSPM_SyncRefMask) { - /* number gives AES index, except for 0 which - corresponds to WordClock */ - case 0: return 0; - case HDSPM_SyncRef0: return 1; - case HDSPM_SyncRef1: return 2; - case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3; - case HDSPM_SyncRef2: return 4; - case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5; - case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6; - case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7; - case HDSPM_SyncRef3: return 8; - } - } else { - switch (hdspm->control_register & HDSPM_SyncRefMask) { - case HDSPM_SyncRef_Word: - return HDSPM_SYNC_FROM_WORD; - case HDSPM_SyncRef_MADI: - return HDSPM_SYNC_FROM_MADI; - } + switch (hdspm->control_register & HDSPM_SyncRefMask) { + case HDSPM_SyncRef_Word: + return HDSPM_SYNC_FROM_WORD; + case HDSPM_SyncRef_MADI: + return HDSPM_SYNC_FROM_MADI; } return HDSPM_SYNC_FROM_WORD; @@ -1609,49 +1469,15 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) { hdspm->control_register &= ~HDSPM_SyncRefMask; - if (hdspm->is_aes32) { - switch (pref) { - case 0: - hdspm->control_register |= 0; - break; - case 1: - hdspm->control_register |= HDSPM_SyncRef0; - break; - case 2: - hdspm->control_register |= HDSPM_SyncRef1; - break; - case 3: - hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0; - break; - case 4: - hdspm->control_register |= HDSPM_SyncRef2; - break; - case 5: - hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0; - break; - case 6: - hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1; - break; - case 7: - hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0; - break; - case 8: - hdspm->control_register |= HDSPM_SyncRef3; - break; - default: - return -1; - } - } else { - switch (pref) { - case HDSPM_SYNC_FROM_MADI: - hdspm->control_register |= HDSPM_SyncRef_MADI; - break; - case HDSPM_SYNC_FROM_WORD: - hdspm->control_register |= HDSPM_SyncRef_Word; - break; - default: - return -1; - } + switch (pref) { + case HDSPM_SYNC_FROM_MADI: + hdspm->control_register |= HDSPM_SyncRef_MADI; + break; + case HDSPM_SYNC_FROM_WORD: + hdspm->control_register |= HDSPM_SyncRef_Word; + break; + default: + return -1; } hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); return 0; @@ -1660,36 +1486,18 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref) static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - if (hdspm->is_aes32) { - static char *texts[] = { "Word", "AES1", "AES2", "AES3", - "AES4", "AES5", "AES6", "AES7", "AES8" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - - uinfo->value.enumerated.items = 9; - - 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]); - } else { - static char *texts[] = { "Word", "MADI" }; + static char *texts[] = { "Word", "MADI" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; - uinfo->value.enumerated.items = 2; + 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]); - } + 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; } @@ -1709,7 +1517,7 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, int change, max; unsigned int val; - max = hdspm->is_aes32 ? 9 : 2; + max = 2; if (!snd_hdspm_use_is_exclusive(hdspm)) return -EBUSY; @@ -1734,64 +1542,40 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol, static int hdspm_autosync_ref(struct hdspm * hdspm) { - if (hdspm->is_aes32) { - unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); - unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF; - if (syncref == 0) - return HDSPM_AES32_AUTOSYNC_FROM_WORD; - if (syncref <= 8) - return syncref; - return HDSPM_AES32_AUTOSYNC_FROM_NONE; - } else { - /* This looks at the autosync selected sync reference */ - unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - - switch (status2 & HDSPM_SelSyncRefMask) { - case HDSPM_SelSyncRef_WORD: - return HDSPM_AUTOSYNC_FROM_WORD; - case HDSPM_SelSyncRef_MADI: - return HDSPM_AUTOSYNC_FROM_MADI; - case HDSPM_SelSyncRef_NVALID: - return HDSPM_AUTOSYNC_FROM_NONE; - default: - return 0; - } + /* This looks at the autosync selected sync reference */ + unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); + switch (status2 & HDSPM_SelSyncRefMask) { + + case HDSPM_SelSyncRef_WORD: + return HDSPM_AUTOSYNC_FROM_WORD; + + case HDSPM_SelSyncRef_MADI: + return HDSPM_AUTOSYNC_FROM_MADI; + + case HDSPM_SelSyncRef_NVALID: + return HDSPM_AUTOSYNC_FROM_NONE; + + default: return 0; } + + return 0; } static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + static char *texts[] = { "WordClock", "MADI", "None" }; - if (hdspm->is_aes32) { - static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", - "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 10; - 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]); - } - else - { - static char *texts[] = { "WordClock", "MADI", "None" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - 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]); - } + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 3; + 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; } @@ -1999,380 +1783,49 @@ static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol, .name = xname, \ .index = xindex, \ .info = snd_hdspm_info_safe_mode, \ - .get = snd_hdspm_get_safe_mode, \ - .put = snd_hdspm_put_safe_mode \ -} - -static int hdspm_safe_mode(struct hdspm * hdspm) -{ - return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0; -} - -static int hdspm_set_safe_mode(struct hdspm * hdspm, int out) -{ - if (out) - hdspm->control_register |= HDSPM_AutoInp; - else - hdspm->control_register &= ~HDSPM_AutoInp; - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_safe_mode(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 snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_safe_mode(hdspm); - hdspm_set_safe_mode(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} - -#define HDSPM_EMPHASIS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_emphasis, \ - .get = snd_hdspm_get_emphasis, \ - .put = snd_hdspm_put_emphasis \ -} - -static int hdspm_emphasis(struct hdspm * hdspm) -{ - return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0; -} - -static int hdspm_set_emphasis(struct hdspm * hdspm, int emp) -{ - if (emp) - hdspm->control_register |= HDSPM_Emphasis; - else - hdspm->control_register &= ~HDSPM_Emphasis; - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_emphasis(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 snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_emphasis(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_emphasis(hdspm); - hdspm_set_emphasis(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} - -#define HDSPM_DOLBY(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_dolby, \ - .get = snd_hdspm_get_dolby, \ - .put = snd_hdspm_put_dolby \ -} - -static int hdspm_dolby(struct hdspm * hdspm) -{ - return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0; -} - -static int hdspm_set_dolby(struct hdspm * hdspm, int dol) -{ - if (dol) - hdspm->control_register |= HDSPM_Dolby; - else - hdspm->control_register &= ~HDSPM_Dolby; - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_dolby(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 snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_dolby(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_dolby(hdspm); - hdspm_set_dolby(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} - -#define HDSPM_PROFESSIONAL(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_professional, \ - .get = snd_hdspm_get_professional, \ - .put = snd_hdspm_put_professional \ -} - -static int hdspm_professional(struct hdspm * hdspm) -{ - return (hdspm->control_register & HDSPM_Professional) ? 1 : 0; -} - -static int hdspm_set_professional(struct hdspm * hdspm, int dol) -{ - if (dol) - hdspm->control_register |= HDSPM_Professional; - else - hdspm->control_register &= ~HDSPM_Professional; - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_professional(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 snd_hdspm_get_professional(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_professional(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_professional(hdspm); - hdspm_set_professional(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} - -#define HDSPM_INPUT_SELECT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_input_select, \ - .get = snd_hdspm_get_input_select, \ - .put = snd_hdspm_put_input_select \ -} - -static int hdspm_input_select(struct hdspm * hdspm) -{ - return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0; -} - -static int hdspm_set_input_select(struct hdspm * hdspm, int out) -{ - if (out) - hdspm->control_register |= HDSPM_InputSelect0; - else - hdspm->control_register &= ~HDSPM_InputSelect0; - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[] = { "optical", "coaxial" }; - - 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 snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_input_select(hdspm); - hdspm_set_input_select(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} - -#define HDSPM_DS_WIRE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_ds_wire, \ - .get = snd_hdspm_get_ds_wire, \ - .put = snd_hdspm_put_ds_wire \ + .get = snd_hdspm_get_safe_mode, \ + .put = snd_hdspm_put_safe_mode \ } -static int hdspm_ds_wire(struct hdspm * hdspm) +static int hdspm_safe_mode(struct hdspm * hdspm) { - return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0; + return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0; } -static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds) +static int hdspm_set_safe_mode(struct hdspm * hdspm, int out) { - if (ds) - hdspm->control_register |= HDSPM_DS_DoubleWire; + if (out) + hdspm->control_register |= HDSPM_AutoInp; else - hdspm->control_register &= ~HDSPM_DS_DoubleWire; + hdspm->control_register &= ~HDSPM_AutoInp; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); return 0; } -static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) +static int snd_hdspm_info_safe_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "Single", "Double" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 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]); - + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; return 0; } -static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm); + ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm); spin_unlock_irq(&hdspm->lock); return 0; } -static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); int change; @@ -2382,56 +1835,45 @@ static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol, return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_ds_wire(hdspm); - hdspm_set_ds_wire(hdspm, val); + change = (int) val != hdspm_safe_mode(hdspm); + hdspm_set_safe_mode(hdspm, val); spin_unlock_irq(&hdspm->lock); return change; } -#define HDSPM_QS_WIRE(xname, xindex) \ +#define HDSPM_INPUT_SELECT(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ .index = xindex, \ - .info = snd_hdspm_info_qs_wire, \ - .get = snd_hdspm_get_qs_wire, \ - .put = snd_hdspm_put_qs_wire \ + .info = snd_hdspm_info_input_select, \ + .get = snd_hdspm_get_input_select, \ + .put = snd_hdspm_put_input_select \ } -static int hdspm_qs_wire(struct hdspm * hdspm) +static int hdspm_input_select(struct hdspm * hdspm) { - if (hdspm->control_register & HDSPM_QS_DoubleWire) - return 1; - if (hdspm->control_register & HDSPM_QS_QuadWire) - return 2; - return 0; + return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0; } -static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode) +static int hdspm_set_input_select(struct hdspm * hdspm, int out) { - hdspm->control_register &= ~(HDSPM_QS_DoubleWire | HDSPM_QS_QuadWire); - switch (mode) { - case 0: - break; - case 1: - hdspm->control_register |= HDSPM_QS_DoubleWire; - break; - case 2: - hdspm->control_register |= HDSPM_QS_QuadWire; - break; - } + if (out) + hdspm->control_register |= HDSPM_InputSelect0; + else + hdspm->control_register &= ~HDSPM_InputSelect0; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); return 0; } -static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, +static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "Single", "Double", "Quad" }; + static char *texts[] = { "optical", "coaxial" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - uinfo->value.enumerated.items = 3; + uinfo->value.enumerated.items = 2; if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = @@ -2442,34 +1884,30 @@ static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, return 0; } -static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol, +static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm); + ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm); spin_unlock_irq(&hdspm->lock); return 0; } -static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, +static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); int change; - int val; + unsigned int val; if (!snd_hdspm_use_is_exclusive(hdspm)) return -EBUSY; - val = ucontrol->value.integer.value[0]; - if (val < 0) - val = 0; - if (val > 2) - val = 2; + val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&hdspm->lock); - change = (int) val != hdspm_qs_wire(hdspm); - hdspm_set_qs_wire(hdspm, val); + change = (int) val != hdspm_input_select(hdspm); + hdspm_set_input_select(hdspm, val); spin_unlock_irq(&hdspm->lock); return change; } @@ -2697,24 +2135,14 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, static int hdspm_wc_sync_check(struct hdspm * hdspm) { - if (hdspm->is_aes32) { - int status = hdspm_read(hdspm, HDSPM_statusRegister); - if (status & HDSPM_AES32_wcLock) { - /* I don't know how to differenciate sync from lock. - Doing as if sync for now */ + int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); + if (status2 & HDSPM_wcLock) { + if (status2 & HDSPM_wcSync) return 2; - } - return 0; - } else { - int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - if (status2 & HDSPM_wcLock) { - if (status2 & HDSPM_wcSync) - return 2; - else - return 1; - } - return 0; + else + return 1; } + return 0; } static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, @@ -2760,43 +2188,9 @@ static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol, } -#define HDSPM_AES_SYNC_CHECK(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ - .info = snd_hdspm_info_sync_check, \ - .get = snd_hdspm_get_aes_sync_check \ -} - -static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx) -{ - int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - if (status2 & (HDSPM_LockAES >> idx)) { - /* I don't know how to differenciate sync from lock. - Doing as if sync for now */ - return 2; - } - return 0; -} - -static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int offset; - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - offset = ucontrol->id.index - 1; - if (offset < 0 || offset >= 8) - return -EINVAL; - - ucontrol->value.enumerated.item[0] = - hdspm_aes_sync_check(hdspm, offset); - return 0; -} -static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { +static struct snd_kcontrol_new snd_hdspm_controls[] = { HDSPM_MIXER("Mixer", 0), /* 'Sample Clock Source' complies with the alsa control naming scheme */ @@ -2817,29 +2211,6 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { HDSPM_INPUT_SELECT("Input Select", 0), }; -static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { - - HDSPM_MIXER("Mixer", 0), -/* 'Sample Clock Source' complies with the alsa control naming scheme */ - HDSPM_CLOCK_SOURCE("Sample Clock Source", 0), - - HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), - HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), - HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), - HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), -/* 'External Rate' complies with the alsa control naming scheme */ - HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), - HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0), -/* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */ - HDSPM_LINE_OUT("Line Out", 0), - HDSPM_EMPHASIS("Emphasis", 0), - HDSPM_DOLBY("Non Audio", 0), - HDSPM_PROFESSIONAL("Professional", 0), - HDSPM_C_TMS("Clear Track Marker", 0), - HDSPM_DS_WIRE("Double Speed Wire Mode", 0), - HDSPM_QS_WIRE("Quad Speed Wire Mode", 0), -}; - static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; @@ -2874,40 +2245,20 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm struct snd_kcontrol *kctl; /* add control list first */ - if (hdspm->is_aes32) { - struct snd_kcontrol_new aes_sync_ctl = - HDSPM_AES_SYNC_CHECK("AES Lock Status", 0); - - for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32); - idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_hdspm_controls_aes32[idx], - hdspm)); - if (err < 0) - return err; - } - for (idx = 1; idx <= 8; idx++) { - aes_sync_ctl.index = idx; - err = snd_ctl_add(card, - snd_ctl_new1(&aes_sync_ctl, hdspm)); - if (err < 0) - return err; - } - } else { - for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi); - idx++) { - err = snd_ctl_add(card, - snd_ctl_new1(&snd_hdspm_controls_madi[idx], - hdspm)); - if (err < 0) - return err; + + for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls); idx++) { + if ((err = + snd_ctl_add(card, kctl = + snd_ctl_new1(&snd_hdspm_controls[idx], + hdspm))) < 0) { + return err; } } /* Channel playback mixer as default control -Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer -they are accesible via special IOCTL on hwdep -and the mixer 2dimensional mixer control */ + Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer + they are accesible via special IOCTL on hwdep + and the mixer 2dimensional mixer control */ snd_hdspm_playback_mixer.name = "Chn"; limit = HDSPM_MAX_CHANNELS; @@ -2938,8 +2289,7 @@ and the mixer 2dimensional mixer control */ ------------------------------------------------------------*/ static void -snd_hdspm_proc_read_madi(struct snd_info_entry * entry, - struct snd_info_buffer *buffer) +snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) { struct hdspm *hdspm = (struct hdspm *) entry->private_data; unsigned int status; @@ -3070,10 +2420,11 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, clock_source = "Error"; } snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); - if (!(hdspm->control_register & HDSPM_ClockModeMaster)) + if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { system_clock_mode = "Slave"; - else + } else { system_clock_mode = "Master"; + } snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); switch (hdspm_pref_sync_ref(hdspm)) { @@ -3133,213 +2484,13 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, snd_iprintf(buffer, "\n"); } -static void -snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, - struct snd_info_buffer *buffer) -{ - struct hdspm *hdspm = (struct hdspm *) entry->private_data; - unsigned int status; - unsigned int status2; - unsigned int timecode; - int pref_syncref; - char *autosync_ref; - char *system_clock_mode; - char *clock_source; - int x; - - status = hdspm_read(hdspm, HDSPM_statusRegister); - status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); - - snd_iprintf(buffer, "%s (Card #%d) Rev.%x\n", - hdspm->card_name, hdspm->card->number + 1, - hdspm->firmware_rev); - - snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", - hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); - - snd_iprintf(buffer, "--- System ---\n"); - - snd_iprintf(buffer, - "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", - status & HDSPM_audioIRQPending, - (status & HDSPM_midi0IRQPending) ? 1 : 0, - (status & HDSPM_midi1IRQPending) ? 1 : 0, - hdspm->irq_count); - snd_iprintf(buffer, - "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n", - ((status & HDSPM_BufferID) ? 1 : 0), - (status & HDSPM_BufferPositionMask), - (status & HDSPM_BufferPositionMask) % (2 * - (int)hdspm-> - period_bytes), - ((status & HDSPM_BufferPositionMask) - - 64) % (2 * (int)hdspm->period_bytes), - (long) hdspm_hw_pointer(hdspm) * 4); - - snd_iprintf(buffer, - "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", - hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, - hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, - 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, - status, status2, timecode); - - snd_iprintf(buffer, "--- Settings ---\n"); - - x = 1 << (6 + - hdspm_decode_latency(hdspm-> - control_register & - HDSPM_LatencyMask)); - - snd_iprintf(buffer, - "Size (Latency): %d samples (2 periods of %lu bytes)\n", - x, (unsigned long) hdspm->period_bytes); - - snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n", - (hdspm-> - control_register & HDSPM_LineOut) ? "on " : "off", - (hdspm->precise_ptr) ? "on" : "off"); - - snd_iprintf(buffer, - "ClearTrackMarker %s, Emphasis %s, Dolby %s\n", - (hdspm-> - control_register & HDSPM_clr_tms) ? "on" : "off", - (hdspm-> - control_register & HDSPM_Emphasis) ? "on" : "off", - (hdspm-> - control_register & HDSPM_Dolby) ? "on" : "off"); - - switch (hdspm_clock_source(hdspm)) { - case HDSPM_CLOCK_SOURCE_AUTOSYNC: - clock_source = "AutoSync"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ: - clock_source = "Internal 32 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ: - clock_source = "Internal 44.1 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ: - clock_source = "Internal 48 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ: - clock_source = "Internal 64 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ: - clock_source = "Internal 88.2 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ: - clock_source = "Internal 96 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ: - clock_source = "Internal 128 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ: - clock_source = "Internal 176.4 kHz"; - break; - case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ: - clock_source = "Internal 192 kHz"; - break; - default: - clock_source = "Error"; - } - snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); - if (!(hdspm->control_register & HDSPM_ClockModeMaster)) - system_clock_mode = "Slave"; - else - system_clock_mode = "Master"; - snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); - - pref_syncref = hdspm_pref_sync_ref(hdspm); - if (pref_syncref == 0) - snd_iprintf(buffer, "Preferred Sync Reference: Word Clock\n"); - else - snd_iprintf(buffer, "Preferred Sync Reference: AES%d\n", - pref_syncref); - - snd_iprintf(buffer, "System Clock Frequency: %d\n", - hdspm->system_sample_rate); - - snd_iprintf(buffer, "Double speed: %s\n", - hdspm->control_register & HDSPM_DS_DoubleWire? - "Double wire" : "Single wire"); - snd_iprintf(buffer, "Quad speed: %s\n", - hdspm->control_register & HDSPM_QS_DoubleWire? - "Double wire" : - hdspm->control_register & HDSPM_QS_QuadWire? - "Quad wire" : "Single wire"); - - snd_iprintf(buffer, "--- Status:\n"); - - snd_iprintf(buffer, "Word: %s Frequency: %d\n", - (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock", - HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF)); - - for (x = 0; x < 8; x++) { - snd_iprintf(buffer, "AES%d: %s Frequency: %d\n", - x+1, - (status2 & (HDSPM_LockAES >> x))? "Sync ": "No Lock", - HDSPM_bit2freq((timecode >> (4*x)) & 0xF)); - } - - switch (hdspm_autosync_ref(hdspm)) { - case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break; - case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break; - case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break; - default: autosync_ref = "---"; break; - } - snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); - - snd_iprintf(buffer, "\n"); -} - -#ifdef CONFIG_SND_DEBUG -static void -snd_hdspm_proc_read_debug(struct snd_info_entry * entry, - struct snd_info_buffer *buffer) -{ - struct hdspm *hdspm = (struct hdspm *)entry->private_data; - - int j,i; - - for (i = 0; i < 256 /* 1024*64 */; i += j) - { - snd_iprintf(buffer, "0x%08X: ", i); - for (j = 0; j < 16; j += 4) - snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j)); - snd_iprintf(buffer, "\n"); - } -} -#endif - - - static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) { struct snd_info_entry *entry; if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) snd_info_set_text_ops(entry, hdspm, - hdspm->is_aes32 ? - snd_hdspm_proc_read_aes32 : - snd_hdspm_proc_read_madi); -#ifdef CONFIG_SND_DEBUG - /* debug file to read all hdspm registers */ - if (!snd_card_proc_new(hdspm->card, "debug", &entry)) - snd_info_set_text_ops(entry, hdspm, - snd_hdspm_proc_read_debug); -#endif + snd_hdspm_proc_read); } /*------------------------------------------------------------ @@ -3356,20 +2507,13 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) /* set defaults: */ - if (hdspm->is_aes32) - hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ - hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ - HDSPM_SyncRef0 | /* AES1 is syncclock */ - HDSPM_LineOut | /* Analog output in */ - HDSPM_Professional; /* Professional mode */ - else - hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ - hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ - HDSPM_InputCoaxial | /* Input Coax not Optical */ - HDSPM_SyncRef_MADI | /* Madi is syncclock */ - HDSPM_LineOut | /* Analog output in */ - HDSPM_TX_64ch | /* transmit in 64ch mode */ - HDSPM_AutoInp; /* AutoInput chossing (takeover) */ + hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ + hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ + HDSPM_InputCoaxial | /* Input Coax not Optical */ + HDSPM_SyncRef_MADI | /* Madi is syncclock */ + HDSPM_LineOut | /* Analog output in */ + HDSPM_TX_64ch | /* transmit in 64ch mode */ + HDSPM_AutoInp; /* AutoInput chossing (takeover) */ /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */ /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */ @@ -3678,8 +2822,6 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, hdspm->playback_buffer = (unsigned char *) substream->runtime->dma_area; - snd_printdd("Allocated sample buffer for playback at %p\n", - hdspm->playback_buffer); } else { hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn, params_channels(params)); @@ -3689,15 +2831,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, hdspm->capture_buffer = (unsigned char *) substream->runtime->dma_area; - snd_printdd("Allocated sample buffer for capture at %p\n", - hdspm->capture_buffer); } - /* - snd_printdd("Allocated sample buffer for %s at 0x%08X\n", - substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - "playback" : "capture", - snd_pcm_sgbuf_get_addr(sgbuf, 0)); - */ return 0; } @@ -3848,10 +2982,9 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 ), + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), .rate_min = 32000, - .rate_max = 192000, + .rate_max = 96000, .channels_min = 1, .channels_max = HDSPM_MAX_CHANNELS, .buffer_bytes_max = @@ -3873,10 +3006,9 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = { SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000), + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), .rate_min = 32000, - .rate_max = 192000, + .rate_max = 96000, .channels_min = 1, .channels_max = HDSPM_MAX_CHANNELS, .buffer_bytes_max = @@ -4183,8 +3315,7 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) pcm = hdspm->pcm; -/* wanted = HDSPM_DMA_AREA_BYTES + 4096;*/ /* dont know why, but it works */ - wanted = HDSPM_DMA_AREA_BYTES; + wanted = HDSPM_DMA_AREA_BYTES + 4096; /* dont know why, but it works */ if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, @@ -4336,16 +3467,9 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp pci_read_config_word(hdspm->pci, PCI_CLASS_REVISION, &hdspm->firmware_rev); - hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION); - + strcpy(card->driver, "HDSPM"); strcpy(card->mixername, "Xilinx FPGA"); - if (hdspm->is_aes32) { - strcpy(card->driver, "HDSPAES32"); - hdspm->card_name = "RME HDSPM AES32"; - } else { - strcpy(card->driver, "HDSPM"); - hdspm->card_name = "RME HDSPM MADI"; - } + hdspm->card_name = "RME HDSPM MADI"; if ((err = pci_enable_device(pci)) < 0) return err; diff --git a/trunk/sound/pci/trident/trident_main.c b/trunk/sound/pci/trident/trident_main.c index 3bff32167f66..474f2d451ae8 100644 --- a/trunk/sound/pci/trident/trident_main.c +++ b/trunk/sound/pci/trident/trident_main.c @@ -2627,7 +2627,7 @@ static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol, return 0; } -static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); +static DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -2844,7 +2844,7 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol, return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); +static DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata = { diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index a28992269f5e..a572b018807f 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -1699,7 +1699,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol, return change; } -static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); +static DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = { .name = "PCM Playback Volume", @@ -1823,7 +1823,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *qui ac97.private_data = chip; ac97.private_free = snd_via82xx_mixer_free_ac97; ac97.pci = chip->pci; - ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_MODEM; if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) return err; @@ -2357,59 +2357,93 @@ static struct via823x_info via823x_cards[] __devinitdata = { /* * auto detection of DXS channel supports. */ - -static struct snd_pci_quirk dxs_whitelist[] __devinitdata = { - SND_PCI_QUIRK(0x1005, 0x4710, "Avance Logic Mobo", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1019, 0x0996, "ESC Mobo", VIA_DXS_48K), - SND_PCI_QUIRK(0x1019, 0x0a81, "ECS K7VTA3 v8.0", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x1019, 0x0a85, "ECS L7VMM2", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x1019, 0, "ESC K8", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1019, 0xaa01, "ESC K8T890-A", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1025, 0x0033, "Acer Inspire 1353LM", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x1025, 0x0046, "Acer Aspire 1524 WLMi", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1043, 0, "ASUS A7/A8", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x1071, 0, "Diverse Notebook", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1106, 0, "ASRock", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte GA-7VAXP", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1462, 0x3800, "MSI KT266", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1462, 0x7120, "MSI KT4V", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1462, 0x7142, "MSI K8MM-V", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1462, 0, "MSI Mobo", VIA_DXS_SRC), - SND_PCI_QUIRK(0x147b, 0x1401, "ABIT KD7(-RAID)", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x147b, 0x1411, "ABIT VA-20", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x147b, 0x1413, "ABIT KV8 Pro", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x147b, 0x1415, "ABIT AV8", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x14ff, 0x0403, "Twinhead mobo", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x14ff, 0x0408, "Twinhead laptop", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1558, 0x4701, "Clevo D470", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1584, 0x8120, "Diverse Laptop", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1584, 0x8123, "Targa/Uniwill", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x161f, 0x202b, "Amira Notebook", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x161f, 0x2032, "m680x machines", VIA_DXS_48K), - SND_PCI_QUIRK(0x1631, 0xe004, "PB EasyNote 3174", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1695, 0x3005, "EPoX EP-8K9A", VIA_DXS_ENABLE), - SND_PCI_QUIRK(0x1695, 0, "EPoX mobo", VIA_DXS_SRC), - SND_PCI_QUIRK(0x16f3, 0, "Jetway K8", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1734, 0, "FSC Laptop", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1849, 0x3059, "ASRock K7VM2", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x1849, 0, "ASRock mobo", VIA_DXS_SRC), - SND_PCI_QUIRK(0x1919, 0x200a, "Soltek SL-K8", VIA_DXS_NO_VRA), - SND_PCI_QUIRK(0x4005, 0x4710, "MSI K7T266", VIA_DXS_SRC), - { } /* terminator */ +struct dxs_whitelist { + unsigned short subvendor; + unsigned short subdevice; + unsigned short mask; + short action; /* new dxs_support value */ }; static int __devinit check_dxs_list(struct pci_dev *pci, int revision) { - const struct snd_pci_quirk *w; + static struct dxs_whitelist whitelist[] __devinitdata = { + { .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */ + { .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K }, + { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */ + { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */ + { .subvendor = 0x1019, .subdevice = 0xa101, .action = VIA_DXS_SRC }, + { .subvendor = 0x1019, .subdevice = 0xaa01, .action = VIA_DXS_SRC }, /* ECS K8T890-A */ + { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */ + { .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */ + { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ + { .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ + { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ + { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */ + { .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ + { .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */ + { .subvendor = 0x1043, .subdevice = 0x81b9, .action = VIA_DXS_SRC }, /* ASUS A8V-MX */ + { .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ + { .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */ + { .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ + { .subvendor = 0x1106, .subdevice = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */ + { .subvendor = 0x1106, .subdevice = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */ + { .subvendor = 0x1106, .subdevice = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */ + { .subvendor = 0x1106, .subdevice = 0xc001, .action = VIA_DXS_SRC }, /* Insight P4-ITX */ + { .subvendor = 0x1297, .subdevice = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */ + { .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */ + { .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */ + { .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */ + { .subvendor = 0x1462, .subdevice = 0x0430, .action = VIA_DXS_SRC }, /* MSI 7142 (K8MM-V) */ + { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */ + { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ + { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ + { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_SRC }, /* MSI K8T Neo2-FI */ + { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ + { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ + { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */ + { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */ + { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */ + { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ + { .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ + { .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */ + { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */ + { .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */ + { .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */ + { .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */ + { .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */ + { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */ + { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */ + { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ + { .subvendor = 0x1695, .subdevice = 0x300c, .action = VIA_DXS_SRC }, /* EPoX EP-8KRAI */ + { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ + { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ + { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */ + { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */ + { .subvendor = 0x1734, .subdevice = 0x10ab, .action = VIA_DXS_SRC }, /* FSC */ + { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ + { .subvendor = 0x1849, .subdevice = 0x9739, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ + { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ + { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ + { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ + { } /* terminator */ + }; + const struct dxs_whitelist *w; + unsigned short subsystem_vendor; + unsigned short subsystem_device; + + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); - w = snd_pci_quirk_lookup(pci, dxs_whitelist); - if (w) { - snd_printdd(KERN_INFO "via82xx: DXS white list for %s found\n", - w->name); - return w->value; + for (w = whitelist; w->subvendor; w++) { + if (w->subvendor != subsystem_vendor) + continue; + if (w->mask) { + if ((w->mask & subsystem_device) == w->subdevice) + return w->action; + } else { + if (subsystem_device == w->subdevice) + return w->action; + } } /* for newer revision, default to DXS_SRC */ diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index b338e15db0d9..17d6b847585f 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -900,7 +900,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip) ac97.private_data = chip; ac97.private_free = snd_via82xx_mixer_free_ac97; ac97.pci = chip->pci; - ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE; + ac97.scaps = AC97_SCAP_SKIP_AUDIO; ac97.num = chip->ac97_secondary; if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) diff --git a/trunk/sound/pci/vx222/vx222.c b/trunk/sound/pci/vx222/vx222.c index 474eac9490ae..89f58ea180b3 100644 --- a/trunk/sound/pci/vx222/vx222.c +++ b/trunk/sound/pci/vx222/vx222.c @@ -73,8 +73,8 @@ MODULE_DEVICE_TABLE(pci, snd_vx222_ids); /* */ -static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); -static const DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0); static struct snd_vx_hardware vx222_old_hw = { diff --git a/trunk/sound/pci/vx222/vx222_ops.c b/trunk/sound/pci/vx222/vx222_ops.c index 55558bef7166..5e51950e05f9 100644 --- a/trunk/sound/pci/vx222/vx222_ops.c +++ b/trunk/sound/pci/vx222/vx222_ops.c @@ -846,7 +846,7 @@ static void vx2_set_input_level(struct snd_vx222 *chip) #define MIC_LEVEL_MAX 0xff -static const DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0); /* * controls API for input levels diff --git a/trunk/sound/pci/ymfpci/ymfpci_image.h b/trunk/sound/pci/ymfpci/ymfpci_image.h index 112f2fff6c8e..1b0746991669 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_image.h +++ b/trunk/sound/pci/ymfpci/ymfpci_image.h @@ -1,7 +1,7 @@ #ifndef _HWMCODE_ #define _HWMCODE_ -static u32 DspInst[YDSXG_DSPLENGTH / 4] = { +static unsigned long DspInst[YDSXG_DSPLENGTH / 4] = { 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, @@ -12,7 +12,7 @@ static u32 DspInst[YDSXG_DSPLENGTH / 4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = { +static unsigned long CntrlInst[YDSXG_CTRLLENGTH / 4] = { 0x000007, 0x240007, 0x0C0007, 0x1C0007, 0x060007, 0x700002, 0x000020, 0x030040, 0x007104, 0x004286, 0x030040, 0x000F0D, @@ -791,7 +791,7 @@ static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = { // 04/09 creat // 04/12 stop nise fix // 06/21 WorkingOff timming -static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { +static unsigned long CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { 0x000007, 0x240007, 0x0C0007, 0x1C0007, 0x060007, 0x700002, 0x000020, 0x030040, 0x007104, 0x004286, 0x030040, 0x000F0D, diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index fd12674d0394..7881944a1957 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -2,6 +2,12 @@ * Copyright (c) by Jaroslav Kysela * Routines for control of YMF724/740/744/754 chips * + * BUGS: + * -- + * + * TODO: + * -- + * * 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 @@ -20,7 +26,6 @@ #include #include -#include #include #include #include @@ -37,7 +42,10 @@ #include #include -#include + +/* + * constants + */ /* * common I/O routines @@ -171,17 +179,6 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate) return val[0]; } -static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm) -{ - unsigned int value; - struct snd_ymfpci_pcm_mixer *mixer; - - mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number]; - value = min_t(unsigned int, mixer->left, 0x7fff) >> 1; - value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16; - snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value); -} - /* * Hardware start management */ @@ -293,10 +290,6 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic snd_assert(pvoice != NULL, return -EINVAL); snd_ymfpci_hw_stop(chip); spin_lock_irqsave(&chip->voice_lock, flags); - if (pvoice->number == chip->src441_used) { - chip->src441_used = -1; - pvoice->ypcm->use_441_slot = 0; - } pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0; pvoice->ypcm = NULL; pvoice->interrupt = NULL; @@ -401,7 +394,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr); - if (ypcm->voices[1] != NULL && !ypcm->use_441_slot) + if (ypcm->voices[1] != NULL) chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr); ypcm->running = 1; break; @@ -409,7 +402,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; - if (ypcm->voices[1] != NULL && !ypcm->use_441_slot) + if (ypcm->voices[1] != NULL) chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0; ypcm->running = 0; break; @@ -496,7 +489,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int unsigned int nbank; u32 vol_left, vol_right; u8 use_left, use_right; - unsigned long flags; snd_assert(voice != NULL, return); if (runtime->channels == 1) { @@ -515,27 +507,11 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int vol_left = cpu_to_le32(0x40000000); vol_right = cpu_to_le32(0x40000000); } - spin_lock_irqsave(&ypcm->chip->voice_lock, flags); format = runtime->channels == 2 ? 0x00010000 : 0; if (snd_pcm_format_width(runtime->format) == 8) format |= 0x80000000; - else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 && - runtime->rate == 44100 && runtime->channels == 2 && - voiceidx == 0 && (ypcm->chip->src441_used == -1 || - ypcm->chip->src441_used == voice->number)) { - ypcm->chip->src441_used = voice->number; - ypcm->use_441_slot = 1; - format |= 0x10000000; - snd_ymfpci_pcm_441_volume_set(ypcm); - } - if (ypcm->chip->src441_used == voice->number && - (format & 0x10000000) == 0) { - ypcm->chip->src441_used = -1; - ypcm->use_441_slot = 0; - } if (runtime->channels == 2 && (voiceidx & 1) != 0) format |= 1; - spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags); for (nbank = 0; nbank < 2; nbank++) { bank = &voice->bank[nbank]; memset(bank, 0, sizeof(*bank)); @@ -1504,7 +1480,7 @@ static int snd_ymfpci_put_single(struct snd_kcontrol *kcontrol, return change; } -static const DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0); +static DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0); #define YMFPCI_DOUBLE(xname, xindex, reg) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ @@ -1746,10 +1722,7 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol, spin_lock_irqsave(&chip->voice_lock, flags); if (substream->runtime && substream->runtime->private_data) { struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; - if (!ypcm->use_441_slot) - ypcm->update_pcm_vol = 2; - else - snd_ymfpci_pcm_441_volume_set(ypcm); + ypcm->update_pcm_vol = 2; } spin_unlock_irqrestore(&chip->voice_lock, flags); return 1; @@ -1998,94 +1971,13 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) } } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL - #include "ymfpci_image.h" -static struct firmware snd_ymfpci_dsp_microcode = { - .size = YDSXG_DSPLENGTH, - .data = (u8 *)DspInst, -}; -static struct firmware snd_ymfpci_controller_microcode = { - .size = YDSXG_CTRLLENGTH, - .data = (u8 *)CntrlInst, -}; -static struct firmware snd_ymfpci_controller_1e_microcode = { - .size = YDSXG_CTRLLENGTH, - .data = (u8 *)CntrlInst1E, -}; -#endif - -#ifdef __LITTLE_ENDIAN -static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } -#else -static void snd_ymfpci_convert_from_le(const struct firmware *fw) -{ - int i; - u32 *data = (u32 *)fw->data; - - for (i = 0; i < fw->size / 4; ++i) - le32_to_cpus(&data[i]); -} -#endif - -static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) -{ - int err, is_1e; - const char *name; - - err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw", - &chip->pci->dev); - if (err >= 0) { - if (chip->dsp_microcode->size == YDSXG_DSPLENGTH) - snd_ymfpci_convert_from_le(chip->dsp_microcode); - else { - snd_printk(KERN_ERR "DSP microcode has wrong size\n"); - err = -EINVAL; - } - } - if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->dsp_microcode = &snd_ymfpci_dsp_microcode; -#else - 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 || - chip->device_id == PCI_DEVICE_ID_YAMAHA_754; - name = is_1e ? "yamaha/ds1e_ctrl.fw" : "yamaha/ds1_ctrl.fw"; - err = request_firmware(&chip->controller_microcode, name, - &chip->pci->dev); - if (err >= 0) { - if (chip->controller_microcode->size == YDSXG_CTRLLENGTH) - snd_ymfpci_convert_from_le(chip->controller_microcode); - else { - snd_printk(KERN_ERR "controller microcode" - " has wrong size\n"); - 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 - return err; -#endif - } - return 0; -} - static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { int i; u16 ctrl; - u32 *inst; + unsigned long *inst; snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000); snd_ymfpci_disable_dsp(chip); @@ -2100,12 +1992,21 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip) snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); /* setup DSP instruction code */ - inst = (u32 *)chip->dsp_microcode->data; for (i = 0; i < YDSXG_DSPLENGTH / 4; i++) - snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]); + snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]); /* setup control instruction code */ - inst = (u32 *)chip->controller_microcode->data; + switch (chip->device_id) { + case PCI_DEVICE_ID_YAMAHA_724F: + case PCI_DEVICE_ID_YAMAHA_740C: + case PCI_DEVICE_ID_YAMAHA_744: + case PCI_DEVICE_ID_YAMAHA_754: + inst = CntrlInst1E; + break; + default: + inst = CntrlInst; + break; + } for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]); @@ -2259,15 +2160,6 @@ 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) -#endif - release_firmware(chip->controller_microcode); kfree(chip); return 0; } @@ -2288,7 +2180,7 @@ static int saved_regs_index[] = { YDSXGR_PRIADCLOOPVOL, YDSXGR_NATIVEDACINVOL, YDSXGR_NATIVEDACOUTVOL, - YDSXGR_BUF441OUTVOL, + // YDSXGR_BUF441OUTVOL, YDSXGR_NATIVEADCINVOL, YDSXGR_SPDIFLOOPVOL, YDSXGR_SPDIFOUTVOL, @@ -2403,7 +2295,6 @@ int __devinit snd_ymfpci_create(struct snd_card *card, chip->reg_area_phys = pci_resource_start(pci, 0); chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000); pci_set_master(pci); - chip->src441_used = -1; if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); @@ -2424,12 +2315,6 @@ int __devinit snd_ymfpci_create(struct snd_card *card, return -EIO; } - err = snd_ymfpci_request_firmware(chip); - if (err < 0) { - snd_printk(KERN_ERR "firmware request failed: %d\n", err); - snd_ymfpci_free(chip); - return err; - } snd_ymfpci_download_image(chip); udelay(100); /* seems we need a delay after downloading image.. */ diff --git a/trunk/sound/pcmcia/vx/vxp_mixer.c b/trunk/sound/pcmcia/vx/vxp_mixer.c index 2b1f996c898d..bced7b623b12 100644 --- a/trunk/sound/pcmcia/vx/vxp_mixer.c +++ b/trunk/sound/pcmcia/vx/vxp_mixer.c @@ -64,7 +64,7 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v return 0; } -static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); +static DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0); static struct snd_kcontrol_new vx_control_mic_level = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 363bcb5f08e6..d7df59e9c647 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -91,7 +91,7 @@ static int snd_vxpocket_dev_free(struct snd_device *device) * Only output levels can be modified */ -static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); +static DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); static struct snd_vx_hardware vxpocket_hw = { .name = "VXPocket", diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig deleted file mode 100644 index ec821a57f843..000000000000 --- a/trunk/sound/soc/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# -# SoC audio configuration -# - -menu "SoC audio support" - depends on SND!=n - -config SND_SOC_AC97_BUS - bool - -config SND_SOC - tristate "SoC audio support" - ---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 - - This SoC 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 - -# Supported codecs -source "sound/soc/codecs/Kconfig" - -endmenu diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile deleted file mode 100644 index 98e6f49dafc2..000000000000 --- a/trunk/sound/soc/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -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/ diff --git a/trunk/sound/soc/at91/Kconfig b/trunk/sound/soc/at91/Kconfig deleted file mode 100644 index 5bcf08b728b0..000000000000 --- a/trunk/sound/soc/at91/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -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 - select SND_PCM - help - Say Y or M if you want to add support for codecs attached to - the AT91 SSC interface. You will also need - to select the audio interfaces to support below. - -config SND_AT91_SOC_I2S - tristate - -config SND_AT91_SOC_ETI_B1_WM8731 - tristate "SoC I2S 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_SOC_WM8731 - help - Say Y if you want to add support for SoC audio on WM8731-based - Endrelia Technologies Inc ETI-B1 or ETI-C1 boards. - -config SND_AT91_SOC_ETI_SLAVE - bool "Run codec in slave Mode on Endrelia boards" - depends on SND_AT91_SOC_ETI_B1_WM8731 - default n - help - Say Y if you want to run with the AT91 SSC generating the BCLK - and LRC signals on Endrelia boards. - -endmenu diff --git a/trunk/sound/soc/at91/Makefile b/trunk/sound/soc/at91/Makefile deleted file mode 100644 index b77b01ab2028..000000000000 --- a/trunk/sound/soc/at91/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# AT91 Platform Support -snd-soc-at91-objs := at91-pcm.o -snd-soc-at91-i2s-objs := at91-i2s.o - -obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o -obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o - -# AT91 Machine Support -snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o - -obj-$(CONFIG_SND_AT91_SOC_ETI_B1_WM8731) += snd-soc-eti-b1-wm8731.o diff --git a/trunk/sound/soc/at91/at91-i2s.c b/trunk/sound/soc/at91/at91-i2s.c deleted file mode 100644 index fcc544a96ba3..000000000000 --- a/trunk/sound/soc/at91/at91-i2s.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * - * Based on pxa2xx Platform drivers by - * Liam Girdwood - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#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 = AT91_PDC_TPR, - .xcr = AT91_PDC_TCR, - .xnpr = AT91_PDC_TNPR, - .xncr = AT91_PDC_TNCR, -}; - -static struct at91_pdc_regs pdc_rx_reg = { - .xpr = AT91_PDC_RPR, - .xcr = AT91_PDC_RCR, - .xnpr = AT91_PDC_RNPR, - .xncr = AT91_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 = AT91_PDC_TXTEN, - .pdc_disable = AT91_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 = AT91_PDC_RXTEN, - .pdc_disable = AT91_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.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.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 + AT91_PDC_RPR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_RCR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_RNPR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_RNCR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_TPR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_TCR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_PDC_TNPR, 0); - at91_ssc_write(ssc_p->ssc.base + AT91_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.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/trunk/sound/soc/at91/at91-i2s.h b/trunk/sound/soc/at91/at91-i2s.h deleted file mode 100644 index f8a875ba0ccc..000000000000 --- a/trunk/sound/soc/at91/at91-i2s.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC - * - * Author: Frank Mandarino - * 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/trunk/sound/soc/at91/at91-pcm.c b/trunk/sound/soc/at91/at91-pcm.c deleted file mode 100644 index e88b12e7cc40..000000000000 --- a/trunk/sound/soc/at91/at91-pcm.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * at91-pcm.c -- ALSA PCM interface for the Atmel AT91 SoC - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * Created: Mar 3, 2006 - * - * Based on pxa2xx-pcm.c by: - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: (C) 2004 MontaVista Software, Inc. - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "at91-pcm.h" - -#if 0 -#define DBG(x...) printk(KERN_INFO "at91-pcm: " x) -#else -#define DBG(x...) -#endif - -static const struct snd_pcm_hardware at91_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .period_bytes_min = 32, - .period_bytes_max = 8192, - .periods_min = 2, - .periods_max = 1024, - .buffer_bytes_max = 32 * 1024, -}; - -struct at91_runtime_data { - struct at91_pcm_dma_params *params; - dma_addr_t dma_buffer; /* physical address of dma buffer */ - dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */ - size_t period_size; - dma_addr_t period_ptr; /* physical address of next period */ - u32 pdc_xpr_save; /* PDC register save */ - u32 pdc_xcr_save; - u32 pdc_xnpr_save; - u32 pdc_xncr_save; -}; - -static void at91_pcm_dma_irq(u32 ssc_sr, - struct snd_pcm_substream *substream) -{ - struct at91_runtime_data *prtd = substream->runtime->private_data; - struct at91_pcm_dma_params *params = prtd->params; - static int count = 0; - - count++; - - if (ssc_sr & params->mask->ssc_endbuf) { - - printk(KERN_WARNING - "at91-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n", - substream->stream == SNDRV_PCM_STREAM_PLAYBACK - ? "underrun" : "overrun", - params->name, ssc_sr, count); - - /* re-start the PDC */ - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_disable); - - prtd->period_ptr += prtd->period_size; - if (prtd->period_ptr >= prtd->dma_buffer_end) { - prtd->period_ptr = prtd->dma_buffer; - } - - at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr); - at91_ssc_write(params->ssc_base + params->pdc->xcr, - prtd->period_size / params->pdc_xfer_size); - - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_enable); - } - - if (ssc_sr & params->mask->ssc_endx) { - - /* Load the PDC next pointer and counter registers */ - prtd->period_ptr += prtd->period_size; - if (prtd->period_ptr >= prtd->dma_buffer_end) { - prtd->period_ptr = prtd->dma_buffer; - } - at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr); - at91_ssc_write(params->ssc_base + params->pdc->xncr, - prtd->period_size / params->pdc_xfer_size); - } - - snd_pcm_period_elapsed(substream); -} - -static int at91_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct at91_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - - /* this may get called several times by oss emulation - * with different params */ - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - prtd->params = rtd->dai->cpu_dai->dma_data; - prtd->params->dma_intr_handler = at91_pcm_dma_irq; - - prtd->dma_buffer = runtime->dma_addr; - prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes; - prtd->period_size = params_period_bytes(params); - - DBG("hw_params: DMA for %s initialized (dma_bytes=%d, period_size=%d)\n", - prtd->params->name, runtime->dma_bytes, prtd->period_size); - return 0; -} - -static int at91_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct at91_runtime_data *prtd = substream->runtime->private_data; - struct at91_pcm_dma_params *params = prtd->params; - - if (params != NULL) { - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_disable); - prtd->params->dma_intr_handler = NULL; - } - - return 0; -} - -static int at91_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct at91_runtime_data *prtd = substream->runtime->private_data; - struct at91_pcm_dma_params *params = prtd->params; - - at91_ssc_write(params->ssc_base + AT91_SSC_IDR, - params->mask->ssc_endx | params->mask->ssc_endbuf); - - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_disable); - return 0; -} - -static int at91_pcm_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct at91_runtime_data *prtd = substream->runtime->private_data; - struct at91_pcm_dma_params *params = prtd->params; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - prtd->period_ptr = prtd->dma_buffer; - - at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr); - at91_ssc_write(params->ssc_base + params->pdc->xcr, - prtd->period_size / params->pdc_xfer_size); - - prtd->period_ptr += prtd->period_size; - at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr); - at91_ssc_write(params->ssc_base + params->pdc->xncr, - prtd->period_size / params->pdc_xfer_size); - - DBG("trigger: period_ptr=%lx, xpr=%lx, xcr=%ld, xnpr=%lx, xncr=%ld\n", - (unsigned long) prtd->period_ptr, - at91_ssc_read(params->ssc_base + params->pdc->xpr), - at91_ssc_read(params->ssc_base + params->pdc->xcr), - at91_ssc_read(params->ssc_base + params->pdc->xnpr), - at91_ssc_read(params->ssc_base + params->pdc->xncr)); - - at91_ssc_write(params->ssc_base + AT91_SSC_IER, - params->mask->ssc_endx | params->mask->ssc_endbuf); - - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_enable); - - DBG("sr=%lx imr=%lx\n", at91_ssc_read(params->ssc_base + AT91_SSC_SR), - at91_ssc_read(params->ssc_base + AT91_SSC_IER)); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_disable); - break; - - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_enable); - break; - - default: - ret = -EINVAL; - } - - return ret; -} - -static snd_pcm_uframes_t at91_pcm_pointer( - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct at91_runtime_data *prtd = runtime->private_data; - struct at91_pcm_dma_params *params = prtd->params; - dma_addr_t ptr; - snd_pcm_uframes_t x; - - ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr); - x = bytes_to_frames(runtime, ptr - prtd->dma_buffer); - - if (x == runtime->buffer_size) - x = 0; - return x; -} - -static int at91_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct at91_runtime_data *prtd; - int ret = 0; - - snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware); - - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - goto out; - - prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL); - if (prtd == NULL) { - ret = -ENOMEM; - goto out; - } - runtime->private_data = prtd; - - out: - return ret; -} - -static int at91_pcm_close(struct snd_pcm_substream *substream) -{ - struct at91_runtime_data *prtd = substream->runtime->private_data; - - kfree(prtd); - return 0; -} - -static int at91_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -struct snd_pcm_ops at91_pcm_ops = { - .open = at91_pcm_open, - .close = at91_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = at91_pcm_hw_params, - .hw_free = at91_pcm_hw_free, - .prepare = at91_pcm_prepare, - .trigger = at91_pcm_trigger, - .pointer = at91_pcm_pointer, - .mmap = at91_pcm_mmap, -}; - -static int at91_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 = at91_pcm_hardware.buffer_bytes_max; - - 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); - - DBG("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", - (void *) buf->area, - (void *) buf->addr, - size); - - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - return 0; -} - -static u64 at91_pcm_dmamask = 0xffffffff; - -static int at91_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) -{ - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &at91_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; - - if (dai->playback.channels_min) { - ret = at91_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (dai->capture.channels_min) { - ret = at91_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - out: - return ret; -} - -static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - 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; - } -} - -#ifdef CONFIG_PM -static int at91_pcm_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct at91_runtime_data *prtd; - struct at91_pcm_dma_params *params; - - if (!runtime) - return 0; - - prtd = runtime->private_data; - params = prtd->params; - - /* disable the PDC and save the PDC registers */ - - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_disable); - - prtd->pdc_xpr_save = at91_ssc_read(params->ssc_base + params->pdc->xpr); - prtd->pdc_xcr_save = at91_ssc_read(params->ssc_base + params->pdc->xcr); - prtd->pdc_xnpr_save = at91_ssc_read(params->ssc_base + params->pdc->xnpr); - prtd->pdc_xncr_save = at91_ssc_read(params->ssc_base + params->pdc->xncr); - - return 0; -} - -static int at91_pcm_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) -{ - struct snd_pcm_runtime *runtime = dai->runtime; - struct at91_runtime_data *prtd; - struct at91_pcm_dma_params *params; - - if (!runtime) - return 0; - - prtd = runtime->private_data; - params = prtd->params; - - /* restore the PDC registers and enable the PDC */ - at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->pdc_xpr_save); - at91_ssc_write(params->ssc_base + params->pdc->xcr, prtd->pdc_xcr_save); - at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->pdc_xnpr_save); - at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->pdc_xncr_save); - - at91_ssc_write(params->ssc_base + AT91_PDC_PTCR, params->mask->pdc_enable); - return 0; -} -#else -#define at91_pcm_suspend NULL -#define at91_pcm_resume NULL -#endif - -struct snd_soc_platform at91_soc_platform = { - .name = "at91-audio", - .pcm_ops = &at91_pcm_ops, - .pcm_new = at91_pcm_new, - .pcm_free = at91_pcm_free_dma_buffers, - .suspend = at91_pcm_suspend, - .resume = at91_pcm_resume, -}; - -EXPORT_SYMBOL_GPL(at91_soc_platform); - -MODULE_AUTHOR("Frank Mandarino "); -MODULE_DESCRIPTION("Atmel AT91 PCM module"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/at91/at91-pcm.h b/trunk/sound/soc/at91/at91-pcm.h deleted file mode 100644 index 58d0f00a07b2..000000000000 --- a/trunk/sound/soc/at91/at91-pcm.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * Created: Mar 3, 2006 - * - * Based on pxa2xx-pcm.h by: - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: MontaVista Software, Inc. - * - * 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_PCM_H -#define _AT91_PCM_H - -#include - -struct at91_ssc_periph { - void __iomem *base; - u32 pid; -}; - -/* - * Registers and status bits that are required by the PCM driver. - */ -struct at91_pdc_regs { - unsigned int xpr; /* PDC recv/trans pointer */ - unsigned int xcr; /* PDC recv/trans counter */ - unsigned int xnpr; /* PDC next recv/trans pointer */ - unsigned int xncr; /* PDC next recv/trans counter */ - unsigned int ptcr; /* PDC transfer control */ -}; - -struct at91_ssc_mask { - u32 ssc_enable; /* SSC recv/trans enable */ - u32 ssc_disable; /* SSC recv/trans disable */ - u32 ssc_endx; /* SSC ENDTX or ENDRX */ - u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */ - u32 pdc_enable; /* PDC recv/trans enable */ - u32 pdc_disable; /* PDC recv/trans disable */ -}; - -/* - * This structure, shared between the PCM driver and the interface, - * contains all information required by the PCM driver to perform the - * PDC DMA operation. All fields except dma_intr_handler() are initialized - * by the interface. The dms_intr_handler() pointer is set by the PCM - * driver and called by the interface SSC interrupt handler if it is - * non-NULL. - */ -struct at91_pcm_dma_params { - char *name; /* stream identifier */ - int pdc_xfer_size; /* PDC counter increment in bytes */ - void __iomem *ssc_base; /* SSC base address */ - struct at91_pdc_regs *pdc; /* PDC receive or transmit registers */ - struct at91_ssc_mask *mask;/* SSC & PDC status bits */ - struct snd_pcm_substream *substream; - void (*dma_intr_handler)(u32, struct snd_pcm_substream *); -}; - -extern struct snd_soc_platform at91_soc_platform; - -#define at91_ssc_read(a) ((unsigned long) __raw_readl(a)) -#define at91_ssc_write(a,v) __raw_writel((v),(a)) - -#endif /* _AT91_PCM_H */ diff --git a/trunk/sound/soc/at91/eti_b1_wm8731.c b/trunk/sound/soc/at91/eti_b1_wm8731.c deleted file mode 100644 index 8179df3bb2f3..000000000000 --- a/trunk/sound/soc/at91/eti_b1_wm8731.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * eti_b1_wm8731 -- SoC audio for AT91RM9200-based Endrelia ETI_B1 board. - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * Created: Mar 29, 2006 - * - * Based on corgi.c by: - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood - * Richard Purdie - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../codecs/wm8731.h" -#include "at91-pcm.h" -#include "at91-i2s.h" - -#if 0 -#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) -#else -#define DBG(x...) -#endif - -#define AT91_PIO_TF1 (1 << (AT91_PIN_PB6 - PIN_BASE) % 32) -#define AT91_PIO_TK1 (1 << (AT91_PIN_PB7 - PIN_BASE) % 32) -#define AT91_PIO_TD1 (1 << (AT91_PIN_PB8 - PIN_BASE) % 32) -#define AT91_PIO_RD1 (1 << (AT91_PIN_PB9 - PIN_BASE) % 32) -#define AT91_PIO_RK1 (1 << (AT91_PIN_PB10 - PIN_BASE) % 32) -#define AT91_PIO_RF1 (1 << (AT91_PIN_PB11 - PIN_BASE) % 32) - -static struct clk *pck1_clk; -static struct clk *pllb_clk; - - -static int eti_b1_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - int ret; - - /* cpu clock is the AT91 master clock sent to the SSC */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, AT91_SYSCLK_MCK, - 60000000, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* codec system clock is supplied by PCK1, set to 12MHz */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, - 12000000, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* Start PCK1 clock. */ - clk_enable(pck1_clk); - DBG("pck1 started\n"); - - return 0; -} - -static void eti_b1_shutdown(struct snd_pcm_substream *substream) -{ - /* Stop PCK1 clock. */ - clk_disable(pck1_clk); - DBG("pck1 stopped\n"); -} - -static int eti_b1_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - int ret; - -#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE - unsigned int rate; - int cmr_div, period; - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* - * The SSC clock dividers depend on the sample rate. The CMR.DIV - * field divides the system master clock MCK to drive the SSC TK - * signal which provides the codec BCLK. The TCMR.PERIOD and - * RCMR.PERIOD fields further divide the BCLK signal to drive - * the SSC TF and RF signals which provide the codec DACLRC and - * ADCLRC clocks. - * - * The dividers were determined through trial and error, where a - * CMR.DIV value is chosen such that the resulting BCLK value is - * divisible, or almost divisible, by (2 * sample rate), and then - * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1. - */ - rate = params_rate(params); - - switch (rate) { - case 8000: - cmr_div = 25; /* BCLK = 60MHz/(2*25) = 1.2MHz */ - period = 74; /* LRC = BCLK/(2*(74+1)) = 8000Hz */ - break; - case 32000: - cmr_div = 7; /* BCLK = 60MHz/(2*7) ~= 4.28571428MHz */ - period = 66; /* LRC = BCLK/(2*(66+1)) = 31982.942Hz */ - break; - case 48000: - cmr_div = 13; /* BCLK = 60MHz/(2*13) ~= 2.3076923MHz */ - period = 23; /* LRC = BCLK/(2*(23+1)) = 48076.923Hz */ - break; - default: - printk(KERN_WARNING "unsupported rate %d on ETI-B1 board\n", rate); - return -EINVAL; - } - - /* set the MCK divider for BCLK */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div); - if (ret < 0) - return ret; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /* set the BCLK divider for DACLRC */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, - AT91SSC_TCMR_PERIOD, period); - } else { - /* set the BCLK divider for ADCLRC */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, - AT91SSC_RCMR_PERIOD, period); - } - if (ret < 0) - return ret; - -#else /* CONFIG_SND_AT91_SOC_ETI_SLAVE */ - /* - * Codec in Master Mode. - */ - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - -#endif /* CONFIG_SND_AT91_SOC_ETI_SLAVE */ - - return 0; -} - -static struct snd_soc_ops eti_b1_ops = { - .startup = eti_b1_startup, - .hw_params = eti_b1_hw_params, - .shutdown = eti_b1_shutdown, -}; - - -static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Int Mic", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), -}; - -static const char *intercon[][3] = { - - /* speaker connected to LHPOUT */ - {"Ext Spk", NULL, "LHPOUT"}, - - /* mic is connected to Mic Jack, with WM8731 Mic Bias */ - {"MICIN", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Int Mic"}, - - /* terminator */ - {NULL, NULL, NULL}, -}; - -/* - * Logic for a wm8731 as connected on a Endrelia ETI-B1 board. - */ -static int eti_b1_wm8731_init(struct snd_soc_codec *codec) -{ - int i; - - DBG("eti_b1_wm8731_init() called\n"); - - /* Add specific widgets */ - for(i = 0; i < ARRAY_SIZE(eti_b1_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &eti_b1_dapm_widgets[i]); - } - - /* Set up specific audio path interconnects */ - for(i = 0; intercon[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, intercon[i][0], - intercon[i][1], intercon[i][2]); - } - - /* not connected */ - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); - - /* always connected */ - snd_soc_dapm_set_endpoint(codec, "Int Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); - - snd_soc_dapm_sync_endpoints(codec); - - return 0; -} - -static struct snd_soc_dai_link eti_b1_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &at91_i2s_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", - .dai_link = &eti_b1_dai, - .num_links = 1, -}; - -static struct wm8731_setup_data eti_b1_wm8731_setup = { - .i2c_address = 0x1a, -}; - -static struct snd_soc_device eti_b1_snd_devdata = { - .machine = &snd_soc_machine_eti_b1, - .platform = &at91_soc_platform, - .codec_dev = &soc_codec_dev_wm8731, - .codec_data = &eti_b1_wm8731_setup, -}; - -static struct platform_device *eti_b1_snd_device; - -static int __init eti_b1_init(void) -{ - int ret; - u32 ssc_pio_lines; - struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data; - - if (!request_mem_region(AT91RM9200_BASE_SSC1, SZ_16K, "soc-audio")) { - DBG("SSC1 memory region is busy\n"); - return -EBUSY; - } - - ssc->base = ioremap(AT91RM9200_BASE_SSC1, SZ_16K); - if (!ssc->base) { - DBG("SSC1 memory ioremap failed\n"); - ret = -ENOMEM; - goto fail_release_mem; - } - - ssc->pid = AT91RM9200_ID_SSC1; - - eti_b1_snd_device = platform_device_alloc("soc-audio", -1); - if (!eti_b1_snd_device) { - DBG("platform device allocation failed\n"); - ret = -ENOMEM; - goto fail_io_unmap; - } - - platform_set_drvdata(eti_b1_snd_device, &eti_b1_snd_devdata); - eti_b1_snd_devdata.dev = &eti_b1_snd_device->dev; - - ret = platform_device_add(eti_b1_snd_device); - if (ret) { - DBG("platform device add failed\n"); - platform_device_put(eti_b1_snd_device); - goto fail_io_unmap; - } - - ssc_pio_lines = AT91_PIO_TF1 | AT91_PIO_TK1 | AT91_PIO_TD1 - | AT91_PIO_RD1 /* | AT91_PIO_RK1 */ | AT91_PIO_RF1; - - /* Reset all PIO registers and assign lines to peripheral A */ - at91_sys_write(AT91_PIOB + PIO_PDR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_ODR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_IFDR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_CODR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_IDR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_MDDR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_PUDR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_ASR, ssc_pio_lines); - at91_sys_write(AT91_PIOB + PIO_OWDR, ssc_pio_lines); - - /* - * Set PCK1 parent to PLLB and its rate to 12 Mhz. - */ - pllb_clk = clk_get(NULL, "pllb"); - pck1_clk = clk_get(NULL, "pck1"); - - clk_set_parent(pck1_clk, pllb_clk); - clk_set_rate(pck1_clk, 12000000); - - DBG("MCLK rate %luHz\n", clk_get_rate(pck1_clk)); - - /* assign the GPIO pin to PCK1 */ - at91_set_B_periph(AT91_PIN_PA24, 0); - -#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE - printk(KERN_INFO "eti_b1_wm8731: Codec in Slave Mode\n"); -#else - printk(KERN_INFO "eti_b1_wm8731: Codec in Master Mode\n"); -#endif - return ret; - -fail_io_unmap: - iounmap(ssc->base); -fail_release_mem: - release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K); - return ret; -} - -static void __exit eti_b1_exit(void) -{ - struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data; - - clk_put(pck1_clk); - clk_put(pllb_clk); - - platform_device_unregister(eti_b1_snd_device); - - iounmap(ssc->base); - release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K); -} - -module_init(eti_b1_init); -module_exit(eti_b1_exit); - -/* Module information */ -MODULE_AUTHOR("Frank Mandarino "); -MODULE_DESCRIPTION("ALSA SoC ETI-B1-WM8731"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig deleted file mode 100644 index 78ac2688e124..000000000000 --- a/trunk/sound/soc/codecs/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config SND_SOC_AC97_CODEC - tristate - depends SND_SOC - -config SND_SOC_WM8731 - tristate - depends SND_SOC - -config SND_SOC_WM8750 - tristate - depends SND_SOC - -config SND_SOC_WM9712 - tristate - depends SND_SOC diff --git a/trunk/sound/soc/codecs/Makefile b/trunk/sound/soc/codecs/Makefile deleted file mode 100644 index 3249a6e4f1d0..000000000000 --- a/trunk/sound/soc/codecs/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -snd-soc-ac97-objs := ac97.o -snd-soc-wm8731-objs := wm8731.o -snd-soc-wm8750-objs := wm8750.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_WM9712) += snd-soc-wm9712.o diff --git a/trunk/sound/soc/codecs/ac97.c b/trunk/sound/soc/codecs/ac97.c deleted file mode 100644 index 55bc55eb6e24..000000000000 --- a/trunk/sound/soc/codecs/ac97.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * ac97.c -- ALSA Soc AC97 codec support - * - * Copyright 2005 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. - * - * Revision history - * 17th Oct 2005 Initial version. - * - * Generic AC97 support. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AC97_VERSION "0.6" - -static int ac97_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->codec; - - int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; - return snd_ac97_set_rate(codec->ac97, reg, runtime->rate); -} - -#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) - -static struct snd_soc_codec_dai ac97_dai = { - .name = "AC97 HiFi", - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = STD_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = STD_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .prepare = ac97_prepare,}, -}; - -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return soc_ac97_ops.read(codec->ac97, reg); -} - -static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - soc_ac97_ops.write(codec->ac97, reg, val); - return 0; -} - -static int ac97_soc_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - struct snd_ac97_bus *ac97_bus; - struct snd_ac97_template ac97_template; - int ret = 0; - - printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); - - socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (socdev->codec == NULL) - return -ENOMEM; - codec = socdev->codec; - mutex_init(&codec->mutex); - - codec->name = "AC97"; - codec->owner = THIS_MODULE; - codec->dai = &ac97_dai; - codec->num_dai = 1; - codec->write = ac97_write; - codec->read = ac97_read; - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if(ret < 0) - goto err; - - /* add codec as bus device for standard ac97 */ - ret = snd_ac97_bus(codec->card, 0, &soc_ac97_ops, NULL, &ac97_bus); - if(ret < 0) - goto bus_err; - - memset(&ac97_template, 0, sizeof(struct snd_ac97_template)); - ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97); - if(ret < 0) - goto bus_err; - - ret = snd_soc_register_card(socdev); - if (ret < 0) - goto bus_err; - return 0; - -bus_err: - snd_soc_free_pcms(socdev); - -err: - kfree(socdev->codec->reg_cache); - kfree(socdev->codec); - socdev->codec = NULL; - return ret; -} - -static int ac97_soc_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->codec; - - if(codec == NULL) - return 0; - - snd_soc_free_pcms(socdev); - kfree(socdev->codec->reg_cache); - kfree(socdev->codec); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_ac97= { - .probe = ac97_soc_probe, - .remove = ac97_soc_remove, -}; - -EXPORT_SYMBOL_GPL(soc_codec_dev_ac97); - -MODULE_DESCRIPTION("Soc Generic AC97 driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/ac97.h b/trunk/sound/soc/codecs/ac97.h deleted file mode 100644 index 930ddfc2321a..000000000000 --- a/trunk/sound/soc/codecs/ac97.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * linux/sound/codecs/ac97.h -- ALSA SoC Layer - * - * Author: Liam Girdwood - * Created: Dec 1st 2005 - * Copyright: Wolfson Microelectronics. PLC. - * - * 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 __LINUX_SND_SOC_AC97_H -#define __LINUX_SND_SOC_AC97_H - -extern struct snd_soc_codec_device soc_codec_dev_ac97; - -#endif diff --git a/trunk/sound/soc/codecs/wm8731.c b/trunk/sound/soc/codecs/wm8731.c deleted file mode 100644 index 7ca0b5268289..000000000000 --- a/trunk/sound/soc/codecs/wm8731.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * wm8731.c -- WM8731 ALSA SoC Audio driver - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on wm8753.c by Liam Girdwood - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8731.h" - -#define AUDIO_NAME "wm8731" -#define WM8731_VERSION "0.13" - -/* - * Debug - */ - -#define WM8731_DEBUG 0 - -#ifdef WM8731_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) - -struct snd_soc_codec_device soc_codec_dev_wm8731; - -/* codec private data */ -struct wm8731_priv { - unsigned int sysclk; -}; - -/* - * wm8731 register cache - * We can't read the WM8731 register space when we are - * using 2 wire for device control, so we cache them instead. - * There is no point in caching the reset register - */ -static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { - 0x0097, 0x0097, 0x0079, 0x0079, - 0x000a, 0x0008, 0x009f, 0x000a, - 0x0000, 0x0000 -}; - -/* - * read wm8731 register cache - */ -static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg == WM8731_RESET) - return 0; - if (reg >= WM8731_CACHEREGNUM) - return -1; - return cache[reg]; -} - -/* - * write wm8731 register cache - */ -static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec, - u16 reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg >= WM8731_CACHEREGNUM) - return; - cache[reg] = value; -} - -/* - * write to the WM8731 register space - */ -static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D9 WM8731 register offset - * D8...D0 register data - */ - data[0] = (reg << 1) | ((value >> 8) & 0x0001); - data[1] = value & 0x00ff; - - wm8731_write_reg_cache (codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0) - -static const char *wm8731_input_select[] = {"Line In", "Mic"}; -static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; - -static const struct soc_enum wm8731_enum[] = { - SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), - SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), -}; - -static const struct snd_kcontrol_new wm8731_snd_controls[] = { - -SOC_DOUBLE_R("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, - 0, 127, 0), -SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, - 7, 1, 0), - -SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0), -SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), - -SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), -SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1), - -SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1), - -SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), -SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), - -SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), -}; - -/* add non dapm controls */ -static int wm8731_add_controls(struct snd_soc_codec *codec) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) { - if ((err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8731_snd_controls[i],codec, NULL))) < 0) - return err; - } - - return 0; -} - -/* Output Mixer */ -static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { -SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), -SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), -SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), -}; - -/* Input mux */ -static const struct snd_kcontrol_new wm8731_input_mux_controls = -SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); - -static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { -SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, - &wm8731_output_mixer_controls[0], - ARRAY_SIZE(wm8731_output_mixer_controls)), -SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1), -SND_SOC_DAPM_OUTPUT("LOUT"), -SND_SOC_DAPM_OUTPUT("LHPOUT"), -SND_SOC_DAPM_OUTPUT("ROUT"), -SND_SOC_DAPM_OUTPUT("RHPOUT"), -SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8731_PWR, 2, 1), -SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &wm8731_input_mux_controls), -SND_SOC_DAPM_PGA("Line Input", WM8731_PWR, 0, 1, NULL, 0), -SND_SOC_DAPM_MICBIAS("Mic Bias", WM8731_PWR, 1, 1), -SND_SOC_DAPM_INPUT("MICIN"), -SND_SOC_DAPM_INPUT("RLINEIN"), -SND_SOC_DAPM_INPUT("LLINEIN"), -}; - -static const char *intercon[][3] = { - /* output mixer */ - {"Output Mixer", "Line Bypass Switch", "Line Input"}, - {"Output Mixer", "HiFi Playback Switch", "DAC"}, - {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, - - /* outputs */ - {"RHPOUT", NULL, "Output Mixer"}, - {"ROUT", NULL, "Output Mixer"}, - {"LHPOUT", NULL, "Output Mixer"}, - {"LOUT", NULL, "Output Mixer"}, - - /* input mux */ - {"Input Mux", "Line In", "Line Input"}, - {"Input Mux", "Mic", "Mic Bias"}, - {"ADC", NULL, "Input Mux"}, - - /* inputs */ - {"Line Input", NULL, "LLINEIN"}, - {"Line Input", NULL, "RLINEIN"}, - {"Mic Bias", NULL, "MICIN"}, - - /* terminator */ - {NULL, NULL, NULL}, -}; - -static int wm8731_add_widgets(struct snd_soc_codec *codec) -{ - int i; - - for(i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); - } - - /* set up audio path interconnects */ - for(i = 0; intercon[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, intercon[i][0], - intercon[i][1], intercon[i][2]); - } - - snd_soc_dapm_new_widgets(codec); - return 0; -} - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u8 sr:4; - u8 bosr:1; - u8 usb:1; -}; - -/* codec mclk clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 48k */ - {12288000, 48000, 256, 0x0, 0x0, 0x0}, - {18432000, 48000, 384, 0x0, 0x1, 0x0}, - {12000000, 48000, 250, 0x0, 0x0, 0x1}, - - /* 32k */ - {12288000, 32000, 384, 0x6, 0x0, 0x0}, - {18432000, 32000, 576, 0x6, 0x1, 0x0}, - {12000000, 32000, 375, 0x6, 0x0, 0x1}, - - /* 8k */ - {12288000, 8000, 1536, 0x3, 0x0, 0x0}, - {18432000, 8000, 2304, 0x3, 0x1, 0x0}, - {11289600, 8000, 1408, 0xb, 0x0, 0x0}, - {16934400, 8000, 2112, 0xb, 0x1, 0x0}, - {12000000, 8000, 1500, 0x3, 0x0, 0x1}, - - /* 96k */ - {12288000, 96000, 128, 0x7, 0x0, 0x0}, - {18432000, 96000, 192, 0x7, 0x1, 0x0}, - {12000000, 96000, 125, 0x7, 0x0, 0x1}, - - /* 44.1k */ - {11289600, 44100, 256, 0x8, 0x0, 0x0}, - {16934400, 44100, 384, 0x8, 0x1, 0x0}, - {12000000, 44100, 272, 0x8, 0x1, 0x1}, - - /* 88.2k */ - {11289600, 88200, 128, 0xf, 0x0, 0x0}, - {16934400, 88200, 192, 0xf, 0x1, 0x0}, - {12000000, 88200, 136, 0xf, 0x1, 0x1}, -}; - -static inline 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 0; -} - -static int wm8731_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 wm8731_priv *wm8731 = codec->private_data; - u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; - int i = get_coeff(wm8731->sysclk, params_rate(params)); - u16 srate = (coeff_div[i].sr << 2) | - (coeff_div[i].bosr << 1) | coeff_div[i].usb; - - wm8731_write(codec, WM8731_SRATE, srate); - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - } - - wm8731_write(codec, WM8731_IFACE, iface); - return 0; -} - -static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->codec; - - /* set active */ - wm8731_write(codec, WM8731_ACTIVE, 0x0001); - - return 0; -} - -static void wm8731_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->codec; - - /* deactivate */ - if (!codec->active) { - udelay(50); - wm8731_write(codec, WM8731_ACTIVE, 0x0); - } -} - -static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; - - if (mute) - wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8); - else - wm8731_write(codec, WM8731_APDIGI, mute_reg); - return 0; -} - -static int wm8731_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 wm8731_priv *wm8731 = codec->private_data; - - switch (freq) { - case 11289600: - case 12000000: - case 12288000: - case 16934400: - case 18432000: - wm8731->sysclk = freq; - return 0; - } - return -EINVAL; -} - - -static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface |= 0x0040; - break; - case SND_SOC_DAIFMT_CBS_CFS: - break; - default: - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= 0x0002; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x0013; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - iface |= 0x0090; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0080; - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= 0x0010; - break; - default: - return -EINVAL; - } - - /* set iface */ - wm8731_write(codec, WM8731_IFACE, iface); - return 0; -} - -static int wm8731_dapm_event(struct snd_soc_codec *codec, int event) -{ - u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; - - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ - /* vref/mid, osc on, dac unmute */ - wm8731_write(codec, WM8731_PWR, reg); - break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ - break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ - /* everything off except vref/vmid, */ - wm8731_write(codec, WM8731_PWR, reg | 0x0040); - break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ - /* everything off, dac mute, inactive */ - wm8731_write(codec, WM8731_ACTIVE, 0x0); - wm8731_write(codec, WM8731_PWR, 0xffff); - break; - } - codec->dapm_state = event; - return 0; -} - -#define WM8731_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 WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct snd_soc_codec_dai wm8731_dai = { - .name = "WM8731", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8731_RATES, - .formats = WM8731_FORMATS,}, - .ops = { - .prepare = wm8731_pcm_prepare, - .hw_params = wm8731_hw_params, - .shutdown = wm8731_shutdown, - }, - .dai_ops = { - .digital_mute = wm8731_mute, - .set_sysclk = wm8731_set_dai_sysclk, - .set_fmt = wm8731_set_dai_fmt, - } -}; -EXPORT_SYMBOL_GPL(wm8731_dai); - -static int wm8731_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; - - wm8731_write(codec, WM8731_ACTIVE, 0x0); - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); - return 0; -} - -static int wm8731_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; - - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { - data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); - } - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - wm8731_dapm_event(codec, codec->suspend_dapm_state); - return 0; -} - -/* - * initialise the WM8731 driver - * register the mixer and dsp interfaces with the kernel - */ -static int wm8731_init(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev->codec; - int reg, ret = 0; - - codec->name = "WM8731"; - codec->owner = THIS_MODULE; - codec->read = wm8731_read_reg_cache; - codec->write = wm8731_write; - codec->dapm_event = wm8731_dapm_event; - codec->dai = &wm8731_dai; - codec->num_dai = 1; - codec->reg_cache_size = sizeof(wm8731_reg); - codec->reg_cache = kmemdup(wm8731_reg, sizeof(wm8731_reg), GFP_KERNEL); - if (codec->reg_cache == NULL) - return -ENOMEM; - - wm8731_reset(codec); - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - printk(KERN_ERR "wm8731: failed to create pcms\n"); - goto pcm_err; - } - - /* power on device */ - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - - /* set the update bits */ - reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); - wm8731_write(codec, WM8731_LOUT1V, reg | 0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); - wm8731_write(codec, WM8731_ROUT1V, reg | 0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); - wm8731_write(codec, WM8731_LINVOL, reg | 0x0100); - reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); - wm8731_write(codec, WM8731_RINVOL, reg | 0x0100); - - wm8731_add_controls(codec); - wm8731_add_widgets(codec); - ret = snd_soc_register_card(socdev); - if (ret < 0) { - printk(KERN_ERR "wm8731: 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; -} - -static struct snd_soc_device *wm8731_socdev; - -#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) - -/* - * WM8731 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 wm8731_i2c_driver; -static struct i2c_client client_template; - -/* If the i2c layer weren't so broken, we could pass this kind of data - around */ - -static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) -{ - struct snd_soc_device *socdev = wm8731_socdev; - struct wm8731_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 = wm8731_init(socdev); - if (ret < 0) { - err("failed to initialise WM8731\n"); - goto err; - } - return ret; - -err: - kfree(codec); - kfree(i2c); - return ret; -} - -static int wm8731_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 wm8731_i2c_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, wm8731_codec_probe); -} - -/* corgi i2c codec control layer */ -static struct i2c_driver wm8731_i2c_driver = { - .driver = { - .name = "WM8731 I2C Codec", - .owner = THIS_MODULE, - }, - .id = I2C_DRIVERID_WM8731, - .attach_adapter = wm8731_i2c_attach, - .detach_client = wm8731_i2c_detach, - .command = NULL, -}; - -static struct i2c_client client_template = { - .name = "WM8731", - .driver = &wm8731_i2c_driver, -}; -#endif - -static int wm8731_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct wm8731_setup_data *setup; - struct snd_soc_codec *codec; - struct wm8731_priv *wm8731; - int ret = 0; - - info("WM8731 Audio Codec %s", WM8731_VERSION); - - setup = socdev->codec_data; - codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (codec == NULL) - return -ENOMEM; - - wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); - if (wm8731 == NULL) { - kfree(codec); - return -ENOMEM; - } - - codec->private_data = wm8731; - socdev->codec = codec; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - wm8731_socdev = socdev; -#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(&wm8731_i2c_driver); - if (ret != 0) - printk(KERN_ERR "can't add i2c driver"); - } -#else - /* Add other interfaces here */ -#endif - return ret; -} - -/* power down chip */ -static int wm8731_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) - wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) - i2c_del_driver(&wm8731_i2c_driver); -#endif - kfree(codec->private_data); - kfree(codec); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8731 = { - .probe = wm8731_probe, - .remove = wm8731_remove, - .suspend = wm8731_suspend, - .resume = wm8731_resume, -}; - -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); - -MODULE_DESCRIPTION("ASoC WM8731 driver"); -MODULE_AUTHOR("Richard Purdie"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8731.h b/trunk/sound/soc/codecs/wm8731.h deleted file mode 100644 index 5bcab6a7afb4..000000000000 --- a/trunk/sound/soc/codecs/wm8731.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * wm8731.h -- WM8731 Soc Audio driver - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on wm8753.h - * - * 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 _WM8731_H -#define _WM8731_H - -/* WM8731 register space */ - -#define WM8731_LINVOL 0x00 -#define WM8731_RINVOL 0x01 -#define WM8731_LOUT1V 0x02 -#define WM8731_ROUT1V 0x03 -#define WM8731_APANA 0x04 -#define WM8731_APDIGI 0x05 -#define WM8731_PWR 0x06 -#define WM8731_IFACE 0x07 -#define WM8731_SRATE 0x08 -#define WM8731_ACTIVE 0x09 -#define WM8731_RESET 0x0f - -#define WM8731_CACHEREGNUM 10 - -#define WM8731_SYSCLK 0 -#define WM8731_DAI 0 - -struct wm8731_setup_data { - unsigned short i2c_address; -}; - -extern struct snd_soc_codec_dai wm8731_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8731; - -#endif diff --git a/trunk/sound/soc/codecs/wm8750.c b/trunk/sound/soc/codecs/wm8750.c deleted file mode 100644 index 7073e8e294fc..000000000000 --- a/trunk/sound/soc/codecs/wm8750.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * wm8750.c -- WM8750 ALSA SoC audio driver - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on WM8753.c - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8750.h" - -#define AUDIO_NAME "WM8750" -#define WM8750_VERSION "0.12" - -/* - * Debug - */ - -#define WM8750_DEBUG 0 - -#ifdef WM8750_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) - -/* codec private data */ -struct wm8750_priv { - unsigned int sysclk; -}; - -/* - * wm8750 register cache - * We can't read the WM8750 register space when we - * are using 2 wire for device control, so we cache them instead. - */ -static const u16 wm8750_reg[] = { - 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ - 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ - 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ - 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ - 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ - 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ - 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ - 0x0079, 0x0079, 0x0079, /* 40 */ -}; - -/* - * read wm8750 register cache - */ -static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg > WM8750_CACHE_REGNUM) - return -1; - return cache[reg]; -} - -/* - * write wm8750 register cache - */ -static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg > WM8750_CACHE_REGNUM) - return; - cache[reg] = value; -} - -static int wm8750_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; - - wm8750_write_reg_cache (codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0) - -/* - * WM8750 Controls - */ -static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"}; -static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; -static const char *wm8750_treble[] = {"8kHz", "4kHz"}; -static const char *wm8750_3d_lc[] = {"200Hz", "500Hz"}; -static const char *wm8750_3d_uc[] = {"2.2kHz", "1.5kHz"}; -static const char *wm8750_3d_func[] = {"Capture", "Playback"}; -static const char *wm8750_alc_func[] = {"Off", "Right", "Left", "Stereo"}; -static const char *wm8750_ng_type[] = {"Constant PGA Gain", - "Mute ADC Output"}; -static const char *wm8750_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA", - "Differential"}; -static const char *wm8750_pga_sel[] = {"Line 1", "Line 2", "Line 3", - "Differential"}; -static const char *wm8750_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut", - "ROUT1"}; -static const char *wm8750_diff_sel[] = {"Line 1", "Line 2"}; -static const char *wm8750_adcpol[] = {"Normal", "L Invert", "R Invert", - "L + R Invert"}; -static const char *wm8750_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; -static const char *wm8750_mono_mux[] = {"Stereo", "Mono (Left)", - "Mono (Right)", "Digital Mono"}; - -static const struct soc_enum wm8750_enum[] = { -SOC_ENUM_SINGLE(WM8750_BASS, 7, 2, wm8750_bass), -SOC_ENUM_SINGLE(WM8750_BASS, 6, 2, wm8750_bass_filter), -SOC_ENUM_SINGLE(WM8750_TREBLE, 6, 2, wm8750_treble), -SOC_ENUM_SINGLE(WM8750_3D, 5, 2, wm8750_3d_lc), -SOC_ENUM_SINGLE(WM8750_3D, 6, 2, wm8750_3d_uc), -SOC_ENUM_SINGLE(WM8750_3D, 7, 2, wm8750_3d_func), -SOC_ENUM_SINGLE(WM8750_ALC1, 7, 4, wm8750_alc_func), -SOC_ENUM_SINGLE(WM8750_NGATE, 1, 2, wm8750_ng_type), -SOC_ENUM_SINGLE(WM8750_LOUTM1, 0, 5, wm8750_line_mux), -SOC_ENUM_SINGLE(WM8750_ROUTM1, 0, 5, wm8750_line_mux), -SOC_ENUM_SINGLE(WM8750_LADCIN, 6, 4, wm8750_pga_sel), /* 10 */ -SOC_ENUM_SINGLE(WM8750_RADCIN, 6, 4, wm8750_pga_sel), -SOC_ENUM_SINGLE(WM8750_ADCTL2, 7, 4, wm8750_out3), -SOC_ENUM_SINGLE(WM8750_ADCIN, 8, 2, wm8750_diff_sel), -SOC_ENUM_SINGLE(WM8750_ADCDAC, 5, 4, wm8750_adcpol), -SOC_ENUM_SINGLE(WM8750_ADCDAC, 1, 4, wm8750_deemph), -SOC_ENUM_SINGLE(WM8750_ADCIN, 6, 4, wm8750_mono_mux), /* 16 */ - -}; - -static const struct snd_kcontrol_new wm8750_snd_controls[] = { - -SOC_DOUBLE_R("Capture Volume", WM8750_LINVOL, WM8750_RINVOL, 0, 63, 0), -SOC_DOUBLE_R("Capture ZC Switch", WM8750_LINVOL, WM8750_RINVOL, 6, 1, 0), -SOC_DOUBLE_R("Capture Switch", WM8750_LINVOL, WM8750_RINVOL, 7, 1, 1), - -SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8750_LOUT1V, - WM8750_ROUT1V, 7, 1, 0), -SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8750_LOUT2V, - WM8750_ROUT2V, 7, 1, 0), - -SOC_ENUM("Playback De-emphasis", wm8750_enum[15]), - -SOC_ENUM("Capture Polarity", wm8750_enum[14]), -SOC_SINGLE("Playback 6dB Attenuate", WM8750_ADCDAC, 7, 1, 0), -SOC_SINGLE("Capture 6dB Attenuate", WM8750_ADCDAC, 8, 1, 0), - -SOC_DOUBLE_R("PCM Volume", WM8750_LDAC, WM8750_RDAC, 0, 255, 0), - -SOC_ENUM("Bass Boost", wm8750_enum[0]), -SOC_ENUM("Bass Filter", wm8750_enum[1]), -SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1), - -SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 0), -SOC_ENUM("Treble Cut-off", wm8750_enum[2]), - -SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0), -SOC_SINGLE("3D Volume", WM8750_3D, 1, 15, 0), -SOC_ENUM("3D Lower Cut-off", wm8750_enum[3]), -SOC_ENUM("3D Upper Cut-off", wm8750_enum[4]), -SOC_ENUM("3D Mode", wm8750_enum[5]), - -SOC_SINGLE("ALC Capture Target Volume", WM8750_ALC1, 0, 7, 0), -SOC_SINGLE("ALC Capture Max Volume", WM8750_ALC1, 4, 7, 0), -SOC_ENUM("ALC Capture Function", wm8750_enum[6]), -SOC_SINGLE("ALC Capture ZC Switch", WM8750_ALC2, 7, 1, 0), -SOC_SINGLE("ALC Capture Hold Time", WM8750_ALC2, 0, 15, 0), -SOC_SINGLE("ALC Capture Decay Time", WM8750_ALC3, 4, 15, 0), -SOC_SINGLE("ALC Capture Attack Time", WM8750_ALC3, 0, 15, 0), -SOC_SINGLE("ALC Capture NG Threshold", WM8750_NGATE, 3, 31, 0), -SOC_ENUM("ALC Capture NG Type", wm8750_enum[4]), -SOC_SINGLE("ALC Capture NG Switch", WM8750_NGATE, 0, 1, 0), - -SOC_SINGLE("Left ADC Capture Volume", WM8750_LADC, 0, 255, 0), -SOC_SINGLE("Right ADC Capture Volume", WM8750_RADC, 0, 255, 0), - -SOC_SINGLE("ZC Timeout Switch", WM8750_ADCTL1, 0, 1, 0), -SOC_SINGLE("Playback Invert Switch", WM8750_ADCTL1, 1, 1, 0), - -SOC_SINGLE("Right Speaker Playback Invert Switch", WM8750_ADCTL2, 4, 1, 0), - -/* Unimplemented */ -/* ADCDAC Bit 0 - ADCHPD */ -/* ADCDAC Bit 4 - HPOR */ -/* ADCTL1 Bit 2,3 - DATSEL */ -/* ADCTL1 Bit 4,5 - DMONOMIX */ -/* ADCTL1 Bit 6,7 - VSEL */ -/* ADCTL2 Bit 2 - LRCM */ -/* ADCTL2 Bit 3 - TRI */ -/* ADCTL3 Bit 5 - HPFLREN */ -/* ADCTL3 Bit 6 - VROI */ -/* ADCTL3 Bit 7,8 - ADCLRM */ -/* ADCIN Bit 4 - LDCM */ -/* ADCIN Bit 5 - RDCM */ - -SOC_DOUBLE_R("Mic Boost", WM8750_LADCIN, WM8750_RADCIN, 4, 3, 0), - -SOC_DOUBLE_R("Bypass Left Playback Volume", WM8750_LOUTM1, - WM8750_LOUTM2, 4, 7, 1), -SOC_DOUBLE_R("Bypass Right Playback Volume", WM8750_ROUTM1, - WM8750_ROUTM2, 4, 7, 1), -SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8750_MOUTM1, - WM8750_MOUTM2, 4, 7, 1), - -SOC_SINGLE("Mono Playback ZC Switch", WM8750_MOUTV, 7, 1, 0), - -SOC_DOUBLE_R("Headphone Playback Volume", WM8750_LOUT1V, WM8750_ROUT1V, - 0, 127, 0), -SOC_DOUBLE_R("Speaker Playback Volume", WM8750_LOUT2V, WM8750_ROUT2V, - 0, 127, 0), - -SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0), - -}; - -/* add non dapm controls */ -static int wm8750_add_controls(struct snd_soc_codec *codec) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(wm8750_snd_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8750_snd_controls[i],codec, NULL)); - if (err < 0) - return err; - } - return 0; -} - -/* - * DAPM Controls - */ - -/* Left Mixer */ -static const struct snd_kcontrol_new wm8750_left_mixer_controls[] = { -SOC_DAPM_SINGLE("Playback Switch", WM8750_LOUTM1, 8, 1, 0), -SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_LOUTM1, 7, 1, 0), -SOC_DAPM_SINGLE("Right Playback Switch", WM8750_LOUTM2, 8, 1, 0), -SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_LOUTM2, 7, 1, 0), -}; - -/* Right Mixer */ -static const struct snd_kcontrol_new wm8750_right_mixer_controls[] = { -SOC_DAPM_SINGLE("Left Playback Switch", WM8750_ROUTM1, 8, 1, 0), -SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_ROUTM1, 7, 1, 0), -SOC_DAPM_SINGLE("Playback Switch", WM8750_ROUTM2, 8, 1, 0), -SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_ROUTM2, 7, 1, 0), -}; - -/* Mono Mixer */ -static const struct snd_kcontrol_new wm8750_mono_mixer_controls[] = { -SOC_DAPM_SINGLE("Left Playback Switch", WM8750_MOUTM1, 8, 1, 0), -SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_MOUTM1, 7, 1, 0), -SOC_DAPM_SINGLE("Right Playback Switch", WM8750_MOUTM2, 8, 1, 0), -SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_MOUTM2, 7, 1, 0), -}; - -/* Left Line Mux */ -static const struct snd_kcontrol_new wm8750_left_line_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[8]); - -/* Right Line Mux */ -static const struct snd_kcontrol_new wm8750_right_line_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[9]); - -/* Left PGA Mux */ -static const struct snd_kcontrol_new wm8750_left_pga_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[10]); - -/* Right PGA Mux */ -static const struct snd_kcontrol_new wm8750_right_pga_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[11]); - -/* Out 3 Mux */ -static const struct snd_kcontrol_new wm8750_out3_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[12]); - -/* Differential Mux */ -static const struct snd_kcontrol_new wm8750_diffmux_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[13]); - -/* Mono ADC Mux */ -static const struct snd_kcontrol_new wm8750_monomux_controls = -SOC_DAPM_ENUM("Route", wm8750_enum[16]); - -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, - &wm8750_left_mixer_controls[0], - ARRAY_SIZE(wm8750_left_mixer_controls)), - SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, - &wm8750_right_mixer_controls[0], - ARRAY_SIZE(wm8750_right_mixer_controls)), - SND_SOC_DAPM_MIXER("Mono Mixer", WM8750_PWR2, 2, 0, - &wm8750_mono_mixer_controls[0], - ARRAY_SIZE(wm8750_mono_mixer_controls)), - - SND_SOC_DAPM_PGA("Right Out 2", WM8750_PWR2, 3, 0, NULL, 0), - SND_SOC_DAPM_PGA("Left Out 2", WM8750_PWR2, 4, 0, NULL, 0), - SND_SOC_DAPM_PGA("Right Out 1", WM8750_PWR2, 5, 0, NULL, 0), - SND_SOC_DAPM_PGA("Left Out 1", WM8750_PWR2, 6, 0, NULL, 0), - SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8750_PWR2, 7, 0), - SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8750_PWR2, 8, 0), - - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8750_PWR1, 1, 0), - SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8750_PWR1, 2, 0), - SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8750_PWR1, 3, 0), - - SND_SOC_DAPM_MUX("Left PGA Mux", WM8750_PWR1, 5, 0, - &wm8750_left_pga_controls), - SND_SOC_DAPM_MUX("Right PGA Mux", WM8750_PWR1, 4, 0, - &wm8750_right_pga_controls), - SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, - &wm8750_left_line_controls), - SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, - &wm8750_right_line_controls), - - SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8750_out3_controls), - SND_SOC_DAPM_PGA("Out 3", WM8750_PWR2, 1, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mono Out 1", WM8750_PWR2, 2, 0, NULL, 0), - - SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, - &wm8750_diffmux_controls), - SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, - &wm8750_monomux_controls), - SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, - &wm8750_monomux_controls), - - SND_SOC_DAPM_OUTPUT("LOUT1"), - SND_SOC_DAPM_OUTPUT("ROUT1"), - SND_SOC_DAPM_OUTPUT("LOUT2"), - SND_SOC_DAPM_OUTPUT("ROUT2"), - SND_SOC_DAPM_OUTPUT("MONO"), - SND_SOC_DAPM_OUTPUT("OUT3"), - - SND_SOC_DAPM_INPUT("LINPUT1"), - SND_SOC_DAPM_INPUT("LINPUT2"), - SND_SOC_DAPM_INPUT("LINPUT3"), - SND_SOC_DAPM_INPUT("RINPUT1"), - SND_SOC_DAPM_INPUT("RINPUT2"), - SND_SOC_DAPM_INPUT("RINPUT3"), -}; - -static const char *audio_map[][3] = { - /* left mixer */ - {"Left Mixer", "Playback Switch", "Left DAC"}, - {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, - {"Left Mixer", "Right Playback Switch", "Right DAC"}, - {"Left Mixer", "Right Bypass Switch", "Right Line Mux"}, - - /* right mixer */ - {"Right Mixer", "Left Playback Switch", "Left DAC"}, - {"Right Mixer", "Left Bypass Switch", "Left Line Mux"}, - {"Right Mixer", "Playback Switch", "Right DAC"}, - {"Right Mixer", "Right Bypass Switch", "Right Line Mux"}, - - /* left out 1 */ - {"Left Out 1", NULL, "Left Mixer"}, - {"LOUT1", NULL, "Left Out 1"}, - - /* left out 2 */ - {"Left Out 2", NULL, "Left Mixer"}, - {"LOUT2", NULL, "Left Out 2"}, - - /* right out 1 */ - {"Right Out 1", NULL, "Right Mixer"}, - {"ROUT1", NULL, "Right Out 1"}, - - /* right out 2 */ - {"Right Out 2", NULL, "Right Mixer"}, - {"ROUT2", NULL, "Right Out 2"}, - - /* mono mixer */ - {"Mono Mixer", "Left Playback Switch", "Left DAC"}, - {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"}, - {"Mono Mixer", "Right Playback Switch", "Right DAC"}, - {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"}, - - /* mono out */ - {"Mono Out 1", NULL, "Mono Mixer"}, - {"MONO1", NULL, "Mono Out 1"}, - - /* out 3 */ - {"Out3 Mux", "VREF", "VREF"}, - {"Out3 Mux", "ROUT1 + Vol", "ROUT1"}, - {"Out3 Mux", "ROUT1", "Right Mixer"}, - {"Out3 Mux", "MonoOut", "MONO1"}, - {"Out 3", NULL, "Out3 Mux"}, - {"OUT3", NULL, "Out 3"}, - - /* Left Line Mux */ - {"Left Line Mux", "Line 1", "LINPUT1"}, - {"Left Line Mux", "Line 2", "LINPUT2"}, - {"Left Line Mux", "Line 3", "LINPUT3"}, - {"Left Line Mux", "PGA", "Left PGA Mux"}, - {"Left Line Mux", "Differential", "Differential Mux"}, - - /* Right Line Mux */ - {"Right Line Mux", "Line 1", "RINPUT1"}, - {"Right Line Mux", "Line 2", "RINPUT2"}, - {"Right Line Mux", "Line 3", "RINPUT3"}, - {"Right Line Mux", "PGA", "Right PGA Mux"}, - {"Right Line Mux", "Differential", "Differential Mux"}, - - /* Left PGA Mux */ - {"Left PGA Mux", "Line 1", "LINPUT1"}, - {"Left PGA Mux", "Line 2", "LINPUT2"}, - {"Left PGA Mux", "Line 3", "LINPUT3"}, - {"Left PGA Mux", "Differential", "Differential Mux"}, - - /* Right PGA Mux */ - {"Right PGA Mux", "Line 1", "RINPUT1"}, - {"Right PGA Mux", "Line 2", "RINPUT2"}, - {"Right PGA Mux", "Line 3", "RINPUT3"}, - {"Right PGA Mux", "Differential", "Differential Mux"}, - - /* Differential Mux */ - {"Differential Mux", "Line 1", "LINPUT1"}, - {"Differential Mux", "Line 1", "RINPUT1"}, - {"Differential Mux", "Line 2", "LINPUT2"}, - {"Differential Mux", "Line 2", "RINPUT2"}, - - /* Left ADC Mux */ - {"Left ADC Mux", "Stereo", "Left PGA Mux"}, - {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"}, - {"Left ADC Mux", "Digital Mono", "Left PGA Mux"}, - - /* Right ADC Mux */ - {"Right ADC Mux", "Stereo", "Right PGA Mux"}, - {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"}, - {"Right ADC Mux", "Digital Mono", "Right PGA Mux"}, - - /* ADC */ - {"Left ADC", NULL, "Left ADC Mux"}, - {"Right ADC", NULL, "Right ADC Mux"}, - - /* terminator */ - {NULL, NULL, NULL}, -}; - -static int wm8750_add_widgets(struct snd_soc_codec *codec) -{ - int i; - - for(i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); - } - - /* set up audio path audio_mapnects */ - 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; -} - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u8 sr:5; - u8 usb:1; -}; - -/* codec hifi mclk clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 8k */ - {12288000, 8000, 1536, 0x6, 0x0}, - {11289600, 8000, 1408, 0x16, 0x0}, - {18432000, 8000, 2304, 0x7, 0x0}, - {16934400, 8000, 2112, 0x17, 0x0}, - {12000000, 8000, 1500, 0x6, 0x1}, - - /* 11.025k */ - {11289600, 11025, 1024, 0x18, 0x0}, - {16934400, 11025, 1536, 0x19, 0x0}, - {12000000, 11025, 1088, 0x19, 0x1}, - - /* 16k */ - {12288000, 16000, 768, 0xa, 0x0}, - {18432000, 16000, 1152, 0xb, 0x0}, - {12000000, 16000, 750, 0xa, 0x1}, - - /* 22.05k */ - {11289600, 22050, 512, 0x1a, 0x0}, - {16934400, 22050, 768, 0x1b, 0x0}, - {12000000, 22050, 544, 0x1b, 0x1}, - - /* 32k */ - {12288000, 32000, 384, 0xc, 0x0}, - {18432000, 32000, 576, 0xd, 0x0}, - {12000000, 32000, 375, 0xa, 0x1}, - - /* 44.1k */ - {11289600, 44100, 256, 0x10, 0x0}, - {16934400, 44100, 384, 0x11, 0x0}, - {12000000, 44100, 272, 0x11, 0x1}, - - /* 48k */ - {12288000, 48000, 256, 0x0, 0x0}, - {18432000, 48000, 384, 0x1, 0x0}, - {12000000, 48000, 250, 0x0, 0x1}, - - /* 88.2k */ - {11289600, 88200, 128, 0x1e, 0x0}, - {16934400, 88200, 192, 0x1f, 0x0}, - {12000000, 88200, 136, 0x1f, 0x1}, - - /* 96k */ - {12288000, 96000, 128, 0xe, 0x0}, - {18432000, 96000, 192, 0xf, 0x0}, - {12000000, 96000, 125, 0xe, 0x1}, -}; - -static inline 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; - } - - printk(KERN_ERR "wm8750: could not get coeff for mclk %d @ rate %d\n", - mclk, rate); - return -EINVAL; -} - -static int wm8750_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 wm8750_priv *wm8750 = codec->private_data; - - switch (freq) { - case 11289600: - case 12000000: - case 12288000: - case 16934400: - case 18432000: - wm8750->sysclk = freq; - return 0; - } - return -EINVAL; -} - -static int wm8750_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface = 0x0040; - break; - case SND_SOC_DAIFMT_CBS_CFS: - break; - default: - return -EINVAL; - } - - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= 0x0002; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x0013; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - iface |= 0x0090; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0080; - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= 0x0010; - break; - default: - return -EINVAL; - } - - wm8750_write(codec, WM8750_IFACE, iface); - return 0; -} - -static int wm8750_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 wm8750_priv *wm8750 = codec->private_data; - u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; - u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; - int coeff = get_coeff(wm8750->sysclk, params_rate(params)); - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= 0x000c; - break; - } - - /* set iface & srate */ - wm8750_write(codec, WM8750_IFACE, iface); - if (coeff >= 0) - wm8750_write(codec, WM8750_SRATE, srate | - (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); - - return 0; -} - -static int wm8750_mute(struct snd_soc_codec_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; - - if (mute) - wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); - else - wm8750_write(codec, WM8750_ADCDAC, mute_reg); - return 0; -} - -static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) -{ - u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; - - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ - /* set vmid to 50k and unmute dac */ - wm8750_write(codec, WM8750_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 */ - wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); - break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ - /* mute dac and set vmid to 500k, enable VREF */ - wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); - break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ - wm8750_write(codec, WM8750_PWR1, 0x0001); - break; - } - codec->dapm_state = event; - return 0; -} - -#define WM8750_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 WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct snd_soc_codec_dai wm8750_dai = { - .name = "WM8750", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8750_RATES, - .formats = WM8750_FORMATS,}, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8750_RATES, - .formats = WM8750_FORMATS,}, - .ops = { - .hw_params = wm8750_pcm_hw_params, - }, - .dai_ops = { - .digital_mute = wm8750_mute, - .set_fmt = wm8750_set_dai_fmt, - .set_sysclk = wm8750_set_dai_sysclk, - }, -}; -EXPORT_SYMBOL_GPL(wm8750_dai); - -static void wm8750_work(struct work_struct *work) -{ - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - wm8750_dapm_event(codec, codec->dapm_state); -} - -static int wm8750_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; - - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); - return 0; -} - -static int wm8750_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; - - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) { - if (i == WM8750_RESET) - continue; - data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); - } - - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - - /* charge wm8750 caps */ - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D0; - schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); - } - - return 0; -} - -/* - * initialise the WM8750 driver - * register the mixer and dsp interfaces with the kernel - */ -static int wm8750_init(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev->codec; - int reg, ret = 0; - - codec->name = "WM8750"; - codec->owner = THIS_MODULE; - codec->read = wm8750_read_reg_cache; - codec->write = wm8750_write; - codec->dapm_event = wm8750_dapm_event; - 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); - if (codec->reg_cache == NULL) - return -ENOMEM; - - wm8750_reset(codec); - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - printk(KERN_ERR "wm8750: failed to create pcms\n"); - goto pcm_err; - } - - /* charge output caps */ - wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); - codec->dapm_state = SNDRV_CTL_POWER_D3hot; - schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); - - /* set the update bits */ - reg = wm8750_read_reg_cache(codec, WM8750_LDAC); - wm8750_write(codec, WM8750_LDAC, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_RDAC); - wm8750_write(codec, WM8750_RDAC, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); - wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); - wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); - wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); - wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); - wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); - reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); - wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); - - wm8750_add_controls(codec); - wm8750_add_widgets(codec); - ret = snd_soc_register_card(socdev); - if (ret < 0) { - printk(KERN_ERR "wm8750: 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 *wm8750_socdev; - -#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) - -/* - * WM8731 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 wm8750_i2c_driver; -static struct i2c_client client_template; - -static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) -{ - struct snd_soc_device *socdev = wm8750_socdev; - struct wm8750_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 = wm8750_init(socdev); - if (ret < 0) { - err("failed to initialise WM8750\n"); - goto err; - } - return ret; - -err: - kfree(codec); - kfree(i2c); - return ret; -} - -static int wm8750_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 wm8750_i2c_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, wm8750_codec_probe); -} - -/* corgi i2c codec control layer */ -static struct i2c_driver wm8750_i2c_driver = { - .driver = { - .name = "WM8750 I2C Codec", - .owner = THIS_MODULE, - }, - .id = I2C_DRIVERID_WM8750, - .attach_adapter = wm8750_i2c_attach, - .detach_client = wm8750_i2c_detach, - .command = NULL, -}; - -static struct i2c_client client_template = { - .name = "WM8750", - .driver = &wm8750_i2c_driver, -}; -#endif - -static int wm8750_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct wm8750_setup_data *setup = socdev->codec_data; - struct snd_soc_codec *codec; - struct wm8750_priv *wm8750; - int ret = 0; - - info("WM8750 Audio Codec %s", WM8750_VERSION); - codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (codec == NULL) - return -ENOMEM; - - wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); - if (wm8750 == NULL) { - kfree(codec); - return -ENOMEM; - } - - codec->private_data = wm8750; - socdev->codec = codec; - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - wm8750_socdev = socdev; - INIT_DELAYED_WORK(&codec->delayed_work, wm8750_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(&wm8750_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 wm8750_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) - wm8750_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(&wm8750_i2c_driver); -#endif - kfree(codec->private_data); - kfree(codec); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8750 = { - .probe = wm8750_probe, - .remove = wm8750_remove, - .suspend = wm8750_suspend, - .resume = wm8750_resume, -}; - -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); - -MODULE_DESCRIPTION("ASoC WM8750 driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8750.h b/trunk/sound/soc/codecs/wm8750.h deleted file mode 100644 index a97a54a6348e..000000000000 --- a/trunk/sound/soc/codecs/wm8750.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on WM8753.h - * - * 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 _WM8750_H -#define _WM8750_H - -/* WM8750 register space */ - -#define WM8750_LINVOL 0x00 -#define WM8750_RINVOL 0x01 -#define WM8750_LOUT1V 0x02 -#define WM8750_ROUT1V 0x03 -#define WM8750_ADCDAC 0x05 -#define WM8750_IFACE 0x07 -#define WM8750_SRATE 0x08 -#define WM8750_LDAC 0x0a -#define WM8750_RDAC 0x0b -#define WM8750_BASS 0x0c -#define WM8750_TREBLE 0x0d -#define WM8750_RESET 0x0f -#define WM8750_3D 0x10 -#define WM8750_ALC1 0x11 -#define WM8750_ALC2 0x12 -#define WM8750_ALC3 0x13 -#define WM8750_NGATE 0x14 -#define WM8750_LADC 0x15 -#define WM8750_RADC 0x16 -#define WM8750_ADCTL1 0x17 -#define WM8750_ADCTL2 0x18 -#define WM8750_PWR1 0x19 -#define WM8750_PWR2 0x1a -#define WM8750_ADCTL3 0x1b -#define WM8750_ADCIN 0x1f -#define WM8750_LADCIN 0x20 -#define WM8750_RADCIN 0x21 -#define WM8750_LOUTM1 0x22 -#define WM8750_LOUTM2 0x23 -#define WM8750_ROUTM1 0x24 -#define WM8750_ROUTM2 0x25 -#define WM8750_MOUTM1 0x26 -#define WM8750_MOUTM2 0x27 -#define WM8750_LOUT2V 0x28 -#define WM8750_ROUT2V 0x29 -#define WM8750_MOUTV 0x2a - -#define WM8750_CACHE_REGNUM 0x2a - -#define WM8750_SYSCLK 0 - -struct wm8750_setup_data { - unsigned short i2c_address; -}; - -extern struct snd_soc_codec_dai wm8750_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8750; - -#endif diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c deleted file mode 100644 index 92a64871bcd0..000000000000 --- a/trunk/sound/soc/codecs/wm9712.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - * wm9712.c -- ALSA Soc WM9712 codec support - * - * Copyright 2006 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. - * - * Revision history - * 4th Feb 2006 Initial version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WM9712_VERSION "0.4" - -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg); -static int ac97_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val); - -/* - * WM9712 register cache - */ -static const u16 wm9712_reg[] = { - 0x6174, 0x8000, 0x8000, 0x8000, // 6 - 0xf0f0, 0xaaa0, 0xc008, 0x6808, // e - 0xe808, 0xaaa0, 0xad00, 0x8000, // 16 - 0xe808, 0x3000, 0x8000, 0x0000, // 1e - 0x0000, 0x0000, 0x0000, 0x000f, // 26 - 0x0405, 0x0410, 0xbb80, 0xbb80, // 2e - 0x0000, 0xbb80, 0x0000, 0x0000, // 36 - 0x0000, 0x2000, 0x0000, 0x0000, // 3e - 0x0000, 0x0000, 0x0000, 0x0000, // 46 - 0x0000, 0x0000, 0xf83e, 0xffff, // 4e - 0x0000, 0x0000, 0x0000, 0xf83e, // 56 - 0x0008, 0x0000, 0x0000, 0x0000, // 5e - 0xb032, 0x3e00, 0x0000, 0x0000, // 66 - 0x0000, 0x0000, 0x0000, 0x0000, // 6e - 0x0000, 0x0000, 0x0000, 0x0006, // 76 - 0x0001, 0x0000, 0x574d, 0x4c12, // 7e - 0x0000, 0x0000 // virtual hp mixers -}; - -/* virtual HP mixers regs */ -#define HPL_MIXER 0x80 -#define HPR_MIXER 0x82 - -static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"}; -static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"}; -static const char *wm9712_out3_src[] = {"Left", "VREF", "Left + Right", - "Mono"}; -static const char *wm9712_spk_src[] = {"Speaker Mix", "Headphone Mix"}; -static const char *wm9712_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; -static const char *wm9712_base[] = {"Linear Control", "Adaptive Boost"}; -static const char *wm9712_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; -static const char *wm9712_mic[] = {"Mic 1", "Differential", "Mic 2", - "Stereo"}; -static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer", - "Line", "Headphone Mixer", "Phone Mixer", "Phone"}; -static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; -static const char *wm9712_diff_sel[] = {"Mic", "Line"}; - -static const struct soc_enum wm9712_enum[] = { -SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), -SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), -SOC_ENUM_SINGLE(AC97_AUX, 9, 4, wm9712_out3_src), -SOC_ENUM_SINGLE(AC97_AUX, 8, 2, wm9712_spk_src), -SOC_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9712_rec_adc), -SOC_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9712_base), -SOC_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9712_rec_gain), -SOC_ENUM_SINGLE(AC97_MIC, 5, 4, wm9712_mic), -SOC_ENUM_SINGLE(AC97_REC_SEL, 8, 8, wm9712_rec_sel), -SOC_ENUM_SINGLE(AC97_REC_SEL, 0, 8, wm9712_rec_sel), -SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9712_ng_type), -SOC_ENUM_SINGLE(0x5c, 8, 2, wm9712_diff_sel), -}; - -static const struct snd_kcontrol_new wm9712_snd_ac97_controls[] = { -SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), -SOC_SINGLE("Speaker Playback Switch", AC97_MASTER, 15, 1, 1), -SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), -SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE,15, 1, 1), - -SOC_SINGLE("Speaker Playback ZC Switch", AC97_MASTER, 7, 1, 0), -SOC_SINGLE("Speaker Playback Invert Switch", AC97_MASTER, 6, 1, 0), -SOC_SINGLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 7, 1, 0), -SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_MONO, 7, 1, 0), -SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 0), - -SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), -SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), -SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), -SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), -SOC_ENUM("ALC Function", wm9712_enum[0]), -SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), -SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), -SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), -SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), -SOC_ENUM("ALC NG Type", wm9712_enum[10]), -SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), - -SOC_SINGLE("Mic Headphone Volume", AC97_VIDEO, 12, 7, 1), -SOC_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), - -SOC_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), -SOC_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), -SOC_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), - -SOC_SINGLE("PCBeep Bypass Headphone Volume", AC97_PC_BEEP, 12, 7, 1), -SOC_SINGLE("PCBeep Bypass Speaker Volume", AC97_PC_BEEP, 8, 7, 1), -SOC_SINGLE("PCBeep Bypass Phone Volume", AC97_PC_BEEP, 4, 7, 1), - -SOC_SINGLE("Aux Playback Headphone Volume", AC97_CD, 12, 7, 1), -SOC_SINGLE("Aux Playback Speaker Volume", AC97_CD, 8, 7, 1), -SOC_SINGLE("Aux Playback Phone Volume", AC97_CD, 4, 7, 1), - -SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 0), -SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1), - -SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), -SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), - -SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), -SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), -SOC_SINGLE("3D Playback Volume", AC97_3D_CONTROL, 0, 15, 0), - -SOC_ENUM("Bass Control", wm9712_enum[5]), -SOC_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), -SOC_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), -SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), -SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 0), -SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 0), - -SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), -SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), -SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), -SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), - -SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), -SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), -SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), -}; - -/* add non dapm controls */ -static int wm9712_add_controls(struct snd_soc_codec *codec) -{ - int err, i; - - for (i = 0; i < ARRAY_SIZE(wm9712_snd_ac97_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm9712_snd_ac97_controls[i],codec, NULL)); - if (err < 0) - return err; - } - return 0; -} - -/* We have to create a fake left and right HP mixers because - * the codec only has a single control that is shared by both channels. - * This makes it impossible to determine the audio path. - */ -static int mixer_event (struct snd_soc_dapm_widget *w, int event) -{ - u16 l, r, beep, line, phone, mic, pcm, aux; - - l = ac97_read(w->codec, HPL_MIXER); - r = ac97_read(w->codec, HPR_MIXER); - beep = ac97_read(w->codec, AC97_PC_BEEP); - mic = ac97_read(w->codec, AC97_VIDEO); - phone = ac97_read(w->codec, AC97_PHONE); - line = ac97_read(w->codec, AC97_LINE); - pcm = ac97_read(w->codec, AC97_PCM); - aux = ac97_read(w->codec, AC97_CD); - - if (l & 0x1 || r & 0x1) - ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff); - else - ac97_write(w->codec, AC97_VIDEO, mic | 0x8000); - - if (l & 0x2 || r & 0x2) - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff); - else - ac97_write(w->codec, AC97_PCM, pcm | 0x8000); - - if (l & 0x4 || r & 0x4) - ac97_write(w->codec, AC97_LINE, line & 0x7fff); - else - ac97_write(w->codec, AC97_LINE, line | 0x8000); - - if (l & 0x8 || r & 0x8) - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff); - else - ac97_write(w->codec, AC97_PHONE, phone | 0x8000); - - if (l & 0x10 || r & 0x10) - ac97_write(w->codec, AC97_CD, aux & 0x7fff); - else - ac97_write(w->codec, AC97_CD, aux | 0x8000); - - if (l & 0x20 || r & 0x20) - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff); - else - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000); - - return 0; -} - -/* Left Headphone Mixers */ -static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0), -}; - -/* Right Headphone Mixers */ -static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0), - SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0), - SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0), - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0), -}; - -/* Speaker Mixer */ -static const struct snd_kcontrol_new wm9712_speaker_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 11, 1, 1), - SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 11, 1, 1), - SOC_DAPM_SINGLE("Phone Bypass Switch", AC97_PHONE, 14, 1, 1), - SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 14, 1, 1), - SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 14, 1, 1), -}; - -/* Phone Mixer */ -static const struct snd_kcontrol_new wm9712_phone_mixer_controls[] = { - SOC_DAPM_SINGLE("PCBeep Bypass Switch", AC97_PC_BEEP, 7, 1, 1), - SOC_DAPM_SINGLE("Aux Playback Switch", AC97_CD, 7, 1, 1), - SOC_DAPM_SINGLE("Line Bypass Switch", AC97_LINE, 13, 1, 1), - SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PCM, 13, 1, 1), - SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_MIC, 14, 1, 1), - SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_MIC, 13, 1, 1), -}; - -/* ALC headphone mux */ -static const struct snd_kcontrol_new wm9712_alc_mux_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[1]); - -/* out 3 mux */ -static const struct snd_kcontrol_new wm9712_out3_mux_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[2]); - -/* spk mux */ -static const struct snd_kcontrol_new wm9712_spk_mux_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[3]); - -/* Capture to Phone mux */ -static const struct snd_kcontrol_new wm9712_capture_phone_mux_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[4]); - -/* Capture left select */ -static const struct snd_kcontrol_new wm9712_capture_selectl_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[8]); - -/* Capture right select */ -static const struct snd_kcontrol_new wm9712_capture_selectr_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[9]); - -/* Mic select */ -static const struct snd_kcontrol_new wm9712_mic_src_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[7]); - -/* diff select */ -static const struct snd_kcontrol_new wm9712_diff_sel_controls = -SOC_DAPM_ENUM("Route", wm9712_enum[11]); - -static const struct snd_soc_dapm_widget wm9712_dapm_widgets[] = { -SND_SOC_DAPM_MUX("ALC Sidetone Mux", SND_SOC_NOPM, 0, 0, - &wm9712_alc_mux_controls), -SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, - &wm9712_out3_mux_controls), -SND_SOC_DAPM_MUX("Speaker Mux", SND_SOC_NOPM, 0, 0, - &wm9712_spk_mux_controls), -SND_SOC_DAPM_MUX("Capture Phone Mux", SND_SOC_NOPM, 0, 0, - &wm9712_capture_phone_mux_controls), -SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0, - &wm9712_capture_selectl_controls), -SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, - &wm9712_capture_selectr_controls), -SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0, - &wm9712_mic_src_controls), -SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, - &wm9712_diff_sel_controls), -SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1, - &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1, - &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls), - mixer_event, SND_SOC_DAPM_POST_REG), -SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1, - &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)), -SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1, - &wm9712_speaker_mixer_controls[0], - ARRAY_SIZE(wm9712_speaker_mixer_controls)), -SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_INT_PAGING, 14, 1), -SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_INT_PAGING, 13, 1), -SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", SND_SOC_NOPM, 0, 0), -SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_INT_PAGING, 12, 1), -SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_INT_PAGING, 11, 1), -SND_SOC_DAPM_PGA("Headphone PGA", AC97_INT_PAGING, 4, 1, NULL, 0), -SND_SOC_DAPM_PGA("Speaker PGA", AC97_INT_PAGING, 3, 1, NULL, 0), -SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0), -SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), -SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), -SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), -SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), -SND_SOC_DAPM_OUTPUT("MONOOUT"), -SND_SOC_DAPM_OUTPUT("HPOUTL"), -SND_SOC_DAPM_OUTPUT("HPOUTR"), -SND_SOC_DAPM_OUTPUT("LOUT2"), -SND_SOC_DAPM_OUTPUT("ROUT2"), -SND_SOC_DAPM_OUTPUT("OUT3"), -SND_SOC_DAPM_INPUT("LINEINL"), -SND_SOC_DAPM_INPUT("LINEINR"), -SND_SOC_DAPM_INPUT("PHONE"), -SND_SOC_DAPM_INPUT("PCBEEP"), -SND_SOC_DAPM_INPUT("MIC1"), -SND_SOC_DAPM_INPUT("MIC2"), -}; - -static const char *audio_map[][3] = { - /* virtual mixer - mixes left & right channels for spk and mono */ - {"AC97 Mixer", NULL, "Left DAC"}, - {"AC97 Mixer", NULL, "Right DAC"}, - - /* Left HP mixer */ - {"Left HP Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Left HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Left HP Mixer", "Phone Bypass Switch", "Phone PGA"}, - {"Left HP Mixer", "Line Bypass Switch", "Line PGA"}, - {"Left HP Mixer", "PCM Playback Switch", "Left DAC"}, - {"Left HP Mixer", "Mic Sidetone Switch", "Mic PGA"}, - {"Left HP Mixer", NULL, "ALC Sidetone Mux"}, - //{"Right HP Mixer", NULL, "HP Mixer"}, - - /* Right HP mixer */ - {"Right HP Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Right HP Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Right HP Mixer", "Phone Bypass Switch", "Phone PGA"}, - {"Right HP Mixer", "Line Bypass Switch", "Line PGA"}, - {"Right HP Mixer", "PCM Playback Switch", "Right DAC"}, - {"Right HP Mixer", "Mic Sidetone Switch", "Mic PGA"}, - {"Right HP Mixer", NULL, "ALC Sidetone Mux"}, - - /* speaker mixer */ - {"Speaker Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Speaker Mixer", "Line Bypass Switch", "Line PGA"}, - {"Speaker Mixer", "PCM Playback Switch", "AC97 Mixer"}, - {"Speaker Mixer", "Phone Bypass Switch", "Phone PGA"}, - {"Speaker Mixer", "Aux Playback Switch", "Aux DAC"}, - - /* Phone mixer */ - {"Phone Mixer", "PCBeep Bypass Switch", "PCBEEP"}, - {"Phone Mixer", "Line Bypass Switch", "Line PGA"}, - {"Phone Mixer", "Aux Playback Switch", "Aux DAC"}, - {"Phone Mixer", "PCM Playback Switch", "AC97 Mixer"}, - {"Phone Mixer", "Mic 1 Sidetone Switch", "Mic PGA"}, - {"Phone Mixer", "Mic 2 Sidetone Switch", "Mic PGA"}, - - /* inputs */ - {"Line PGA", NULL, "LINEINL"}, - {"Line PGA", NULL, "LINEINR"}, - {"Phone PGA", NULL, "PHONE"}, - {"Mic PGA", NULL, "MIC1"}, - {"Mic PGA", NULL, "MIC2"}, - - /* left capture selector */ - {"Left Capture Select", "Mic", "MIC1"}, - {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, - {"Left Capture Select", "Line", "LINEINL"}, - {"Left Capture Select", "Headphone Mixer", "Left HP Mixer"}, - {"Left Capture Select", "Phone Mixer", "Phone Mixer"}, - {"Left Capture Select", "Phone", "PHONE"}, - - /* right capture selector */ - {"Right Capture Select", "Mic", "MIC2"}, - {"Right Capture Select", "Speaker Mixer", "Speaker Mixer"}, - {"Right Capture Select", "Line", "LINEINR"}, - {"Right Capture Select", "Headphone Mixer", "Right HP Mixer"}, - {"Right Capture Select", "Phone Mixer", "Phone Mixer"}, - {"Right Capture Select", "Phone", "PHONE"}, - - /* ALC Sidetone */ - {"ALC Sidetone Mux", "Stereo", "Left Capture Select"}, - {"ALC Sidetone Mux", "Stereo", "Right Capture Select"}, - {"ALC Sidetone Mux", "Left", "Left Capture Select"}, - {"ALC Sidetone Mux", "Right", "Right Capture Select"}, - - /* ADC's */ - {"Left ADC", NULL, "Left Capture Select"}, - {"Right ADC", NULL, "Right Capture Select"}, - - /* outputs */ - {"MONOOUT", NULL, "Phone Mixer"}, - {"HPOUTL", NULL, "Headphone PGA"}, - {"Headphone PGA", NULL, "Left HP Mixer"}, - {"HPOUTR", NULL, "Headphone PGA"}, - {"Headphone PGA", NULL, "Right HP Mixer"}, - - /* mono hp mixer */ - {"Mono HP Mixer", NULL, "Left HP Mixer"}, - {"Mono HP Mixer", NULL, "Right HP Mixer"}, - - /* Out3 Mux */ - {"Out3 Mux", "Left", "Left HP Mixer"}, - {"Out3 Mux", "Mono", "Phone Mixer"}, - {"Out3 Mux", "Left + Right", "Mono HP Mixer"}, - {"Out 3 PGA", NULL, "Out3 Mux"}, - {"OUT3", NULL, "Out 3 PGA"}, - - /* speaker Mux */ - {"Speaker Mux", "Speaker Mix", "Speaker Mixer"}, - {"Speaker Mux", "Headphone Mix", "Mono HP Mixer"}, - {"Speaker PGA", NULL, "Speaker Mux"}, - {"LOUT2", NULL, "Speaker PGA"}, - {"ROUT2", NULL, "Speaker PGA"}, - - {NULL, NULL, NULL}, -}; - -static int wm9712_add_widgets(struct snd_soc_codec *codec) -{ - int i; - - for(i = 0; i < ARRAY_SIZE(wm9712_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm9712_dapm_widgets[i]); - } - - /* set up audio path audio_mapnects */ - 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; -} - -static unsigned int ac97_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - - if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || - reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || - reg == AC97_REC_GAIN) - return soc_ac97_ops.read(codec->ac97, reg); - else { - reg = reg >> 1; - - if (reg > (ARRAY_SIZE(wm9712_reg))) - return -EIO; - - return cache[reg]; - } -} - -static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - u16 *cache = codec->reg_cache; - - soc_ac97_ops.write(codec->ac97, reg, val); - reg = reg >> 1; - if (reg <= (ARRAY_SIZE(wm9712_reg))) - cache[reg] = val; - - return 0; -} - -static int ac97_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->codec; - int reg; - u16 vra; - - vra = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = AC97_PCM_FRONT_DAC_RATE; - else - reg = AC97_PCM_LR_ADC_RATE; - - return ac97_write(codec, reg, runtime->rate); -} - -static int ac97_aux_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_codec *codec = socdev->codec; - u16 vra, xsle; - - vra = ac97_read(codec, AC97_EXTENDED_STATUS); - ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); - xsle = ac97_read(codec, AC97_PCI_SID); - ac97_write(codec, AC97_PCI_SID, xsle | 0x8000); - - if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - - return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); -} - -#define WM9712_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) - -struct snd_soc_codec_dai wm9712_dai[] = { -{ - .name = "AC97 HiFi", - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .prepare = ac97_prepare,}, -}, -{ - .name = "AC97 Aux", - .playback = { - .stream_name = "Aux Playback", - .channels_min = 1, - .channels_max = 1, - .rates = WM9712_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .prepare = ac97_aux_prepare,}, -} -}; -EXPORT_SYMBOL_GPL(wm9712_dai); - -static int wm9712_dapm_event(struct snd_soc_codec *codec, int event) -{ - u16 reg; - - switch (event) { - case SNDRV_CTL_POWER_D0: /* full On */ - /* liam - maybe enable thermal shutdown */ - reg = ac97_read(codec, AC97_EXTENDED_MID) & 0xdfff; - ac97_write(codec, AC97_EXTENDED_MID, reg); - break; - case SNDRV_CTL_POWER_D1: /* partial On */ - case SNDRV_CTL_POWER_D2: /* partial On */ - break; - case SNDRV_CTL_POWER_D3hot: /* Off, with power */ - /* enable master bias and vmid */ - reg = ac97_read(codec, AC97_EXTENDED_MID) & 0xbbff; - ac97_write(codec, AC97_EXTENDED_MID, reg); - ac97_write(codec, AC97_POWERDOWN, 0x0000); - break; - case SNDRV_CTL_POWER_D3cold: /* Off, without power */ - /* disable everything including AC link */ - ac97_write(codec, AC97_EXTENDED_MID, 0xffff); - ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); - ac97_write(codec, AC97_POWERDOWN, 0xffff); - break; - } - codec->dapm_state = event; - return 0; -} - -static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) -{ - if (try_warm && soc_ac97_ops.warm_reset) { - soc_ac97_ops.warm_reset(codec->ac97); - if (!(ac97_read(codec, 0) & 0x8000)) - return 1; - } - - soc_ac97_ops.reset(codec->ac97); - if (ac97_read(codec, 0) & 0x8000) - goto err; - return 0; - -err: - printk(KERN_ERR "WM9712 AC97 reset failed\n"); - return -EIO; -} - -static int wm9712_soc_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; - - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3cold); - return 0; -} - -static int wm9712_soc_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->codec; - int i, ret; - u16 *cache = codec->reg_cache; - - ret = wm9712_reset(codec, 1); - if (ret < 0){ - printk(KERN_ERR "could not reset AC97 codec\n"); - return ret; - } - - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - - if (ret == 0) { - /* Sync reg_cache with the hardware after cold reset */ - for (i = 2; i < ARRAY_SIZE(wm9712_reg) << 1; i+=2) { - if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || - (i > 0x58 && i != 0x5c)) - continue; - soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); - } - } - - if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D0); - - return ret; -} - -static int wm9712_soc_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); - - socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (socdev->codec == NULL) - return -ENOMEM; - codec = socdev->codec; - mutex_init(&codec->mutex); - - codec->reg_cache = - kzalloc(sizeof(u16) * ARRAY_SIZE(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_step = 2; - - codec->name = "WM9712"; - codec->owner = THIS_MODULE; - codec->dai = wm9712_dai; - codec->num_dai = ARRAY_SIZE(wm9712_dai); - codec->write = ac97_write; - codec->read = ac97_read; - codec->dapm_event = wm9712_dapm_event; - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); - if (ret < 0) { - printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); - goto codec_err; - } - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) - goto pcm_err; - - ret = wm9712_reset(codec, 0); - if (ret < 0) { - printk(KERN_ERR "AC97 link error\n"); - goto reset_err; - } - - /* set alc mux to none */ - ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); - - wm9712_dapm_event(codec, SNDRV_CTL_POWER_D3hot); - wm9712_add_controls(codec); - wm9712_add_widgets(codec); - ret = snd_soc_register_card(socdev); - if (ret < 0) { - printk(KERN_ERR "wm9712: failed to register card\n"); - goto reset_err; - } - - return 0; - -reset_err: - snd_soc_free_pcms(socdev); - -pcm_err: - snd_soc_free_ac97_codec(codec); - -codec_err: - kfree(codec->reg_cache); - -cache_err: - kfree(socdev->codec); - socdev->codec = NULL; - return ret; -} - -static int wm9712_soc_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->codec; - - if (codec == NULL) - return 0; - - snd_soc_dapm_free(socdev); - snd_soc_free_pcms(socdev); - snd_soc_free_ac97_codec(codec); - kfree(codec->reg_cache); - kfree(codec); - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm9712 = { - .probe = wm9712_soc_probe, - .remove = wm9712_soc_remove, - .suspend = wm9712_soc_suspend, - .resume = wm9712_soc_resume, -}; - -EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712); - -MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm9712.h b/trunk/sound/soc/codecs/wm9712.h deleted file mode 100644 index 719105d61e65..000000000000 --- a/trunk/sound/soc/codecs/wm9712.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * wm9712.h -- WM9712 Soc Audio driver - */ - -#ifndef _WM9712_H -#define _WM9712_H - -#define WM9712_DAI_AC97_HIFI 0 -#define WM9712_DAI_AC97_AUX 1 - -extern struct snd_soc_codec_dai wm9712_dai[2]; -extern struct snd_soc_codec_device soc_codec_dev_wm9712; - -#endif diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig deleted file mode 100644 index 579e1c8d2b28..000000000000 --- a/trunk/sound/soc/pxa/Kconfig +++ /dev/null @@ -1,60 +0,0 @@ -menu "SoC Audio for the Intel PXA2xx" - -config SND_PXA2XX_SOC - tristate "SoC Audio for the Intel PXA2xx chip" - depends on ARCH_PXA && SND - select SND_PCM - help - Say Y or M if you want to add support for codecs attached to - the PXA2xx AC97, I2S or SSP interface. You will also need - to select the audio interfaces to support below. - -config SND_PXA2XX_AC97 - tristate - select SND_AC97_CODEC - -config SND_PXA2XX_SOC_AC97 - tristate - select AC97_BUS - select SND_SOC_AC97_BUS - -config SND_PXA2XX_SOC_I2S - tristate - -config SND_PXA2XX_SOC_CORGI - tristate "SoC Audio support for Sharp Zaurus SL-C7x0" - depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8731 - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-C7x0 models (Corgi, Shepherd, Husky). - -config SND_PXA2XX_SOC_SPITZ - tristate "SoC Audio support for Sharp Zaurus SL-Cxx00" - depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8750 - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). - -config SND_PXA2XX_SOC_POODLE - tristate "SoC Audio support for Poodle" - depends on SND_PXA2XX_SOC && MACH_POODLE - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8731 - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-5600 model (Poodle). - -config SND_PXA2XX_SOC_TOSA - tristate "SoC AC97 Audio support for Tosa" - depends on SND_PXA2XX_SOC && MACH_TOSA - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9712 - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-C6000x models (Tosa). - -endmenu diff --git a/trunk/sound/soc/pxa/Makefile b/trunk/sound/soc/pxa/Makefile deleted file mode 100644 index 78e0d6b07d1d..000000000000 --- a/trunk/sound/soc/pxa/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# PXA Platform Support -snd-soc-pxa2xx-objs := pxa2xx-pcm.o -snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o -snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o - -obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o -obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o -obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o - -# PXA Machine Support -snd-soc-corgi-objs := corgi.o -snd-soc-poodle-objs := poodle.o -snd-soc-tosa-objs := tosa.o -snd-soc-spitz-objs := spitz.o - -obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o -obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o -obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o -obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o - diff --git a/trunk/sound/soc/pxa/corgi.c b/trunk/sound/soc/pxa/corgi.c deleted file mode 100644 index 5ee51a994ac3..000000000000 --- a/trunk/sound/soc/pxa/corgi.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * corgi.c -- SoC audio for Corgi - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood - * Richard Purdie - * - * 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 - * 30th Nov 2005 Initial version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../codecs/wm8731.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-i2s.h" - -#define CORGI_HP 0 -#define CORGI_MIC 1 -#define CORGI_LINE 2 -#define CORGI_HEADSET 3 -#define CORGI_HP_OFF 4 -#define CORGI_SPK_ON 0 -#define CORGI_SPK_OFF 1 - - /* audio clock in Hz - rounded from 12.235MHz */ -#define CORGI_AUDIO_CLOCK 12288000 - -static int corgi_jack_func; -static int corgi_spk_func; - -static void corgi_ext_control(struct snd_soc_codec *codec) -{ - int spk = 0, mic = 0, line = 0, hp = 0, hs = 0; - - /* set up jack connection */ - switch (corgi_jack_func) { - case CORGI_HP: - hp = 1; - /* set = unmute headphone */ - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); - break; - case CORGI_MIC: - mic = 1; - /* reset = mute headphone */ - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); - break; - case CORGI_LINE: - line = 1; - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); - break; - case CORGI_HEADSET: - hs = 1; - mic = 1; - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); - break; - } - - if (corgi_spk_func == CORGI_SPK_ON) - spk = 1; - - /* set the enpoints to their new connetion states */ - snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", mic); - snd_soc_dapm_set_endpoint(codec, "Line Jack", line); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs); - - /* signal a DAPM event */ - snd_soc_dapm_sync_endpoints(codec); -} - -static int corgi_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* check the jack status at stream startup */ - corgi_ext_control(codec); - return 0; -} - -/* we need to unmute the HP at shutdown as the mute burns power on corgi */ -static int corgi_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* set = unmute headphone */ - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); - return 0; -} - -static int corgi_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops corgi_ops = { - .startup = corgi_startup, - .hw_params = corgi_hw_params, - .shutdown = corgi_shutdown, -}; - -static int corgi_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = corgi_jack_func; - return 0; -} - -static int corgi_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (corgi_jack_func == ucontrol->value.integer.value[0]) - return 0; - - corgi_jack_func = ucontrol->value.integer.value[0]; - corgi_ext_control(codec); - return 1; -} - -static int corgi_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = corgi_spk_func; - return 0; -} - -static int corgi_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (corgi_spk_func == ucontrol->value.integer.value[0]) - return 0; - - corgi_spk_func = ucontrol->value.integer.value[0]; - corgi_ext_control(codec); - return 1; -} - -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - - return 0; -} - -static int corgi_mic_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); - - return 0; -} - -/* corgi machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", NULL), -SND_SOC_DAPM_MIC("Mic Jack", corgi_mic_event), -SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event), -SND_SOC_DAPM_LINE("Line Jack", NULL), -SND_SOC_DAPM_HP("Headset Jack", NULL), -}; - -/* Corgi machine audio map (connections to the codec pins) */ -static const char *audio_map[][3] = { - - /* headset Jack - in = micin, out = LHPOUT*/ - {"Headset Jack", NULL, "LHPOUT"}, - - /* headphone connected to LHPOUT1, RHPOUT1 */ - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - /* speaker connected to LOUT, ROUT */ - {"Ext Spk", NULL, "ROUT"}, - {"Ext Spk", NULL, "LOUT"}, - - /* mic is connected to MICIN (via right channel of headphone jack) */ - {"MICIN", NULL, "Mic Jack"}, - - /* Same as the above but no mic bias for line signals */ - {"MICIN", NULL, "Line Jack"}, - - {NULL, NULL, NULL}, -}; - -static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", - "Off"}; -static const char *spk_function[] = {"On", "Off"}; -static const struct soc_enum corgi_enum[] = { - SOC_ENUM_SINGLE_EXT(5, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new wm8731_corgi_controls[] = { - SOC_ENUM_EXT("Jack Function", corgi_enum[0], corgi_get_jack, - corgi_set_jack), - SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk, - corgi_set_spk), -}; - -/* - * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device - */ -static int corgi_wm8731_init(struct snd_soc_codec *codec) -{ - int i, err; - - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); - - /* Add corgi specific controls */ - for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8731_corgi_controls[i],codec, NULL)); - if (err < 0) - return err; - } - - /* Add corgi specific widgets */ - for(i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); - } - - /* Set up corgi specific audio path 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_sync_endpoints(codec); - return 0; -} - -/* corgi digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link corgi_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8731_dai, - .init = corgi_wm8731_init, - .ops = &corgi_ops, -}; - -/* corgi audio machine driver */ -static struct snd_soc_machine snd_soc_machine_corgi = { - .name = "Corgi", - .dai_link = &corgi_dai, - .num_links = 1, -}; - -/* corgi audio private data */ -static struct wm8731_setup_data corgi_wm8731_setup = { - .i2c_address = 0x1b, -}; - -/* corgi audio subsystem */ -static struct snd_soc_device corgi_snd_devdata = { - .machine = &snd_soc_machine_corgi, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8731, - .codec_data = &corgi_wm8731_setup, -}; - -static struct platform_device *corgi_snd_device; - -static int __init corgi_init(void) -{ - int ret; - - if (!(machine_is_corgi() || machine_is_shepherd() || machine_is_husky())) - return -ENODEV; - - corgi_snd_device = platform_device_alloc("soc-audio", -1); - if (!corgi_snd_device) - return -ENOMEM; - - platform_set_drvdata(corgi_snd_device, &corgi_snd_devdata); - corgi_snd_devdata.dev = &corgi_snd_device->dev; - ret = platform_device_add(corgi_snd_device); - - if (ret) - platform_device_put(corgi_snd_device); - - return ret; -} - -static void __exit corgi_exit(void) -{ - platform_device_unregister(corgi_snd_device); -} - -module_init(corgi_init); -module_exit(corgi_exit); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Corgi"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/poodle.c b/trunk/sound/soc/pxa/poodle.c deleted file mode 100644 index 0915cf740421..000000000000 --- a/trunk/sound/soc/pxa/poodle.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * poodle.c -- SoC audio for Poodle - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood - * Richard Purdie - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../codecs/wm8731.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-i2s.h" - -#define POODLE_HP 1 -#define POODLE_HP_OFF 0 -#define POODLE_SPK_ON 1 -#define POODLE_SPK_OFF 0 - - /* audio clock in Hz - rounded from 12.235MHz */ -#define POODLE_AUDIO_CLOCK 12288000 - -static int poodle_jack_func; -static int poodle_spk_func; - -static void poodle_ext_control(struct snd_soc_codec *codec) -{ - int spk = 0; - - /* set up jack connection */ - if (poodle_jack_func == POODLE_HP) { - /* set = unmute headphone */ - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_L, 1); - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_R, 1); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); - } else { - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_L, 0); - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_R, 0); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - } - - if (poodle_spk_func == POODLE_SPK_ON) - spk = 1; - - /* set the enpoints to their new connetion states */ - snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk); - - /* signal a DAPM event */ - snd_soc_dapm_sync_endpoints(codec); -} - -static int poodle_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* check the jack status at stream startup */ - poodle_ext_control(codec); - return 0; -} - -/* we need to unmute the HP at shutdown as the mute burns power on poodle */ -static int poodle_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* set = unmute headphone */ - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_L, 1); - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_R, 1); - return 0; -} - -static int poodle_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops poodle_ops = { - .startup = poodle_startup, - .hw_params = poodle_hw_params, - .shutdown = poodle_shutdown, -}; - -static int poodle_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = poodle_jack_func; - return 0; -} - -static int poodle_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (poodle_jack_func == ucontrol->value.integer.value[0]) - return 0; - - poodle_jack_func = ucontrol->value.integer.value[0]; - poodle_ext_control(codec); - return 1; -} - -static int poodle_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = poodle_spk_func; - return 0; -} - -static int poodle_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (poodle_spk_func == ucontrol->value.integer.value[0]) - return 0; - - poodle_spk_func = ucontrol->value.integer.value[0]; - poodle_ext_control(codec); - return 1; -} - -static int poodle_amp_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_AMP_ON, 0); - else - locomo_gpio_write(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_AMP_ON, 1); - - return 0; -} - -/* poodle machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", NULL), -SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event), -}; - -/* Corgi machine audio_mapnections to the codec pins */ -static const char *audio_map[][3] = { - - /* headphone connected to LHPOUT1, RHPOUT1 */ - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - /* speaker connected to LOUT, ROUT */ - {"Ext Spk", NULL, "ROUT"}, - {"Ext Spk", NULL, "LOUT"}, - - {NULL, NULL, NULL}, -}; - -static const char *jack_function[] = {"Off", "Headphone"}; -static const char *spk_function[] = {"Off", "On"}; -static const struct soc_enum poodle_enum[] = { - SOC_ENUM_SINGLE_EXT(2, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const snd_kcontrol_new_t wm8731_poodle_controls[] = { - SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack, - poodle_set_jack), - SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk, - poodle_set_spk), -}; - -/* - * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device - */ -static int poodle_wm8731_init(struct snd_soc_codec *codec) -{ - int i, err; - - snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0); - snd_soc_dapm_set_endpoint(codec, "MICIN", 1); - - /* Add poodle specific controls */ - for (i = 0; i < ARRAY_SIZE(wm8731_poodle_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8731_poodle_controls[i],codec, NULL)); - if (err < 0) - return err; - } - - /* Add poodle specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); - } - - /* Set up poodle specific audio path 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_sync_endpoints(codec); - return 0; -} - -/* poodle digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link poodle_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8731_dai, - .init = poodle_wm8731_init, - .ops = &poodle_ops, -}; - -/* poodle audio machine driver */ -static struct snd_soc_machine snd_soc_machine_poodle = { - .name = "Poodle", - .dai_link = &poodle_dai, - .num_links = 1, -}; - -/* poodle audio private data */ -static struct wm8731_setup_data poodle_wm8731_setup = { - .i2c_address = 0x1b, -}; - -/* poodle audio subsystem */ -static struct snd_soc_device poodle_snd_devdata = { - .machine = &snd_soc_machine_poodle, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8731, - .codec_data = &poodle_wm8731_setup, -}; - -static struct platform_device *poodle_snd_device; - -static int __init poodle_init(void) -{ - int ret; - - if (!machine_is_poodle()) - return -ENODEV; - - locomo_gpio_set_dir(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_AMP_ON, 0); - /* should we mute HP at startup - burning power ?*/ - locomo_gpio_set_dir(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_L, 0); - locomo_gpio_set_dir(&poodle_locomo_device.dev, - POODLE_LOCOMO_GPIO_MUTE_R, 0); - - poodle_snd_device = platform_device_alloc("soc-audio", -1); - if (!poodle_snd_device) - return -ENOMEM; - - platform_set_drvdata(poodle_snd_device, &poodle_snd_devdata); - poodle_snd_devdata.dev = &poodle_snd_device->dev; - ret = platform_device_add(poodle_snd_device); - - if (ret) - platform_device_put(poodle_snd_device); - - return ret; -} - -static void __exit poodle_exit(void) -{ - platform_device_unregister(poodle_snd_device); -} - -module_init(poodle_init); -module_exit(poodle_exit); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Poodle"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/pxa2xx-ac97.c b/trunk/sound/soc/pxa/pxa2xx-ac97.c deleted file mode 100644 index 1bbbeff84ef0..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-ac97.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip. - * - * Author: Nicolas Pitre - * Created: Dec 02, 2004 - * Copyright: MontaVista Software Inc. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pxa2xx-pcm.h" -#include "pxa2xx-ac97.h" - -static DEFINE_MUTEX(car_mutex); -static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); -static volatile long gsr_bits; - -/* - * Beware PXA27x bugs: - * - * o Slot 12 read from modem space will hang controller. - * o CDONE, SDONE interrupt fails after any slot 12 IO. - * - * We therefore have an hybrid approach for waiting on SDONE (interrupt or - * 1 jiffy timeout if interrupt never comes). - */ - -static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - unsigned short val = -1; - volatile u32 *reg_addr; - - mutex_lock(&car_mutex); - - /* set up primary or secondary codec/modem space */ -#ifdef CONFIG_PXA27x - reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; -#else - if (reg == AC97_GPIO_STATUS) - reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; - else - reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; -#endif - reg_addr += (reg >> 1); - -#ifndef CONFIG_PXA27x - if (reg == AC97_GPIO_STATUS) { - /* read from controller cache */ - val = *reg_addr; - goto out; - } -#endif - - /* start read access across the ac97 link */ - GSR = GSR_CDONE | GSR_SDONE; - gsr_bits = 0; - val = *reg_addr; - - wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); - if (!((GSR | gsr_bits) & GSR_SDONE)) { - printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n", - __FUNCTION__, reg, GSR | gsr_bits); - val = -1; - goto out; - } - - /* valid data now */ - GSR = GSR_CDONE | GSR_SDONE; - gsr_bits = 0; - val = *reg_addr; - /* but we've just started another cycle... */ - wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); - -out: mutex_unlock(&car_mutex); - return val; -} - -static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - volatile u32 *reg_addr; - - mutex_lock(&car_mutex); - - /* set up primary or secondary codec/modem space */ -#ifdef CONFIG_PXA27x - reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; -#else - if (reg == AC97_GPIO_STATUS) - reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; - else - reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; -#endif - reg_addr += (reg >> 1); - - GSR = GSR_CDONE | GSR_SDONE; - gsr_bits = 0; - *reg_addr = val; - wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1); - if (!((GSR | gsr_bits) & GSR_CDONE)) - printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n", - __FUNCTION__, reg, GSR | gsr_bits); - - mutex_unlock(&car_mutex); -} - -static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) -{ - gsr_bits = 0; - -#ifdef CONFIG_PXA27x - /* warm reset broken on Bulverde, - so manually keep AC97 reset high */ - pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); - udelay(10); - GCR |= GCR_WARM_RST; - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); - udelay(500); -#else - GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN; - wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); -#endif - - if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) - printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", - __FUNCTION__, gsr_bits); - - GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); - GCR |= GCR_SDONE_IE|GCR_CDONE_IE; -} - -static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) -{ - GCR &= GCR_COLD_RST; /* clear everything but nCRST */ - GCR &= ~GCR_COLD_RST; /* then assert nCRST */ - - gsr_bits = 0; -#ifdef CONFIG_PXA27x - /* PXA27x Developers Manual section 13.5.2.2.1 */ - pxa_set_cken(1 << 31, 1); - udelay(5); - pxa_set_cken(1 << 31, 0); - GCR = GCR_COLD_RST; - udelay(50); -#else - GCR = GCR_COLD_RST; - GCR |= GCR_CDONE_IE|GCR_SDONE_IE; - wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); -#endif - - if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) - printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", - __FUNCTION__, gsr_bits); - - GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); - GCR |= GCR_SDONE_IE|GCR_CDONE_IE; -} - -static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id) -{ - long status; - - status = GSR; - if (status) { - GSR = status; - gsr_bits |= status; - wake_up(&gsr_wq); - -#ifdef CONFIG_PXA27x - /* Although we don't use those we still need to clear them - since they tend to spuriously trigger when MMC is used - (hardware bug? go figure)... */ - MISR = MISR_EOC; - PISR = PISR_EOC; - MCSR = MCSR_EOC; -#endif - - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = pxa2xx_ac97_read, - .write = pxa2xx_ac97_write, - .warm_reset = pxa2xx_ac97_warm_reset, - .reset = pxa2xx_ac97_cold_reset, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { - .name = "AC97 PCM Stereo out", - .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRTXPCDR, - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { - .name = "AC97 PCM Stereo in", - .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRRXPCDR, - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { - .name = "AC97 Aux PCM (Slot 5) Mono out", - .dev_addr = __PREG(MODR), - .drcmr = &DRCMRTXMODR, - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { - .name = "AC97 Aux PCM (Slot 5) Mono in", - .dev_addr = __PREG(MODR), - .drcmr = &DRCMRRXMODR, - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { - .name = "AC97 Mic PCM (Slot 6) Mono in", - .dev_addr = __PREG(MCDR), - .drcmr = &DRCMRRXMCDR, - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -#ifdef CONFIG_PM -static int pxa2xx_ac97_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) -{ - GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN2_AC97, 0); - return 0; -} - -static int pxa2xx_ac97_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) -{ - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); -#ifdef CONFIG_PXA27x - /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); -#endif - pxa_set_cken(CKEN2_AC97, 1); - return 0; -} - -#else -#define pxa2xx_ac97_suspend NULL -#define pxa2xx_ac97_resume NULL -#endif - -static int pxa2xx_ac97_probe(struct platform_device *pdev) -{ - int ret; - - ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); - if (ret < 0) - goto err; - - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); -#ifdef CONFIG_PXA27x - /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); -#endif - pxa_set_cken(CKEN2_AC97, 1); - return 0; - - err: - if (CKEN & CKEN2_AC97) { - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); - } - return ret; -} - -static void pxa2xx_ac97_remove(struct platform_device *pdev) -{ - GCR |= GCR_ACLINK_OFF; - free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN2_AC97, 0); -} - -static int pxa2xx_ac97_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; - else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in; - - return 0; -} - -static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; - else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in; - - return 0; -} - -static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in; - - return 0; -} - -#define PXA2XX_AC97_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) - -/* - * There is only 1 physical AC97 interface for pxa2xx, but it - * has extra fifo's that can be used for aux DACs and ADCs. - */ -struct snd_soc_cpu_dai pxa_ac97_dai[] = { -{ - .name = "pxa2xx-ac97", - .id = 0, - .type = SND_SOC_DAI_AC97, - .probe = pxa2xx_ac97_probe, - .remove = pxa2xx_ac97_remove, - .suspend = pxa2xx_ac97_suspend, - .resume = pxa2xx_ac97_resume, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = PXA2XX_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = PXA2XX_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = pxa2xx_ac97_hw_params,}, -}, -{ - .name = "pxa2xx-ac97-aux", - .id = 1, - .type = SND_SOC_DAI_AC97, - .playback = { - .stream_name = "AC97 Aux Playback", - .channels_min = 1, - .channels_max = 1, - .rates = PXA2XX_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Aux Capture", - .channels_min = 1, - .channels_max = 1, - .rates = PXA2XX_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = pxa2xx_ac97_hw_aux_params,}, -}, -{ - .name = "pxa2xx-ac97-mic", - .id = 2, - .type = SND_SOC_DAI_AC97, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = PXA2XX_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = pxa2xx_ac97_hw_mic_params,}, -}, -}; - -EXPORT_SYMBOL_GPL(pxa_ac97_dai); -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -MODULE_AUTHOR("Nicolas Pitre"); -MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/pxa2xx-ac97.h b/trunk/sound/soc/pxa/pxa2xx-ac97.h deleted file mode 100644 index 4c4b882316ac..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-ac97.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-ac97.h - * - * 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 _PXA2XX_AC97_H -#define _PXA2XX_AC97_H - -/* pxa2xx DAI ID's */ -#define PXA2XX_DAI_AC97_HIFI 0 -#define PXA2XX_DAI_AC97_AUX 1 -#define PXA2XX_DAI_AC97_MIC 2 - -extern struct snd_soc_cpu_dai pxa_ac97_dai[3]; - -/* platform data */ -extern struct snd_ac97_bus_ops pxa2xx_ac97_ops; - -#endif diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c deleted file mode 100644 index 575a6137c040..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * pxa2xx-i2s.c -- ALSA Soc Audio Layer - * - * Copyright 2005 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. - * - * Revision history - * 12th Aug 2005 Initial version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "pxa2xx-pcm.h" -#include "pxa2xx-i2s.h" - -struct pxa_i2s_port { - u32 sadiv; - u32 sacr0; - u32 sacr1; - u32 saimr; - int master; - u32 fmt; -}; -static struct pxa_i2s_port pxa_i2s; - -static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { - .name = "I2S PCM Stereo out", - .dev_addr = __PREG(SADR), - .drcmr = &DRCMRTXSADR, - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { - .name = "I2S PCM Stereo in", - .dev_addr = __PREG(SADR), - .drcmr = &DRCMRRXSADR, - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST32 | DCMD_WIDTH4, -}; - -static struct pxa2xx_gpio gpio_bus[] = { - { /* I2S SoC Slave */ - .rx = GPIO29_SDATA_IN_I2S_MD, - .tx = GPIO30_SDATA_OUT_I2S_MD, - .clk = GPIO28_BITCLK_IN_I2S_MD, - .frm = GPIO31_SYNC_I2S_MD, - }, - { /* I2S SoC Master */ -#ifdef CONFIG_PXA27x - .sys = GPIO113_I2S_SYSCLK_MD, -#else - .sys = GPIO32_SYSCLK_I2S_MD, -#endif - .rx = GPIO29_SDATA_IN_I2S_MD, - .tx = GPIO30_SDATA_OUT_I2S_MD, - .clk = GPIO28_BITCLK_OUT_I2S_MD, - .frm = GPIO31_SYNC_I2S_MD, - }, -}; - -static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (!cpu_dai->active) { - SACR0 |= SACR0_RST; - SACR0 = 0; - } - - return 0; -} - -/* wait for I2S controller to be ready */ -static int pxa_i2s_wait(void) -{ - int i; - - /* flush the Rx FIFO */ - for(i = 0; i < 16; i++) - SADR; - return 0; -} - -static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, - unsigned int fmt) -{ - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - pxa_i2s.fmt = 0; - break; - case SND_SOC_DAIFMT_LEFT_J: - pxa_i2s.fmt = SACR1_AMSL; - break; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - pxa_i2s.master = 1; - break; - case SND_SOC_DAIFMT_CBM_CFS: - pxa_i2s.master = 0; - break; - default: - break; - } - return 0; -} - -static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - if (clk_id != PXA2XX_I2S_SYSCLK) - return -ENODEV; - - if (pxa_i2s.master && dir == SND_SOC_CLOCK_OUT) - pxa_gpio_mode(gpio_bus[pxa_i2s.master].sys); - - return 0; -} - -static int pxa2xx_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_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - pxa_gpio_mode(gpio_bus[pxa_i2s.master].rx); - pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); - pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); - pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); - pxa_set_cken(CKEN8_I2S, 1); - pxa_i2s_wait(); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out; - else - cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in; - - /* is port used by another stream */ - if (!(SACR0 & SACR0_ENB)) { - - SACR0 = 0; - SACR1 = 0; - if (pxa_i2s.master) - SACR0 |= SACR0_BCKD; - - SACR0 |= SACR0_RFTH(14) | SACR0_TFTH(1); - SACR1 |= pxa_i2s.fmt; - } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - SAIMR |= SAIMR_TFS; - else - SAIMR |= SAIMR_RFS; - - switch (params_rate(params)) { - case 8000: - SADIV = 0x48; - break; - case 11025: - SADIV = 0x34; - break; - case 16000: - SADIV = 0x24; - break; - case 22050: - SADIV = 0x1a; - break; - case 44100: - SADIV = 0xd; - break; - case 48000: - SADIV = 0xc; - break; - case 96000: /* not in manual and possibly slightly inaccurate */ - SADIV = 0x6; - break; - } - - return 0; -} - -static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) -{ - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - SACR0 |= SACR0_ENB; - break; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) -{ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - SACR1 |= SACR1_DRPL; - SAIMR &= ~SAIMR_TFS; - } else { - SACR1 |= SACR1_DREC; - SAIMR &= ~SAIMR_RFS; - } - - if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { - SACR0 &= ~SACR0_ENB; - pxa_i2s_wait(); - pxa_set_cken(CKEN8_I2S, 0); - } -} - -#ifdef CONFIG_PM -static int pxa2xx_i2s_suspend(struct platform_device *dev, - struct snd_soc_cpu_dai *dai) -{ - if (!dai->active) - return 0; - - /* store registers */ - pxa_i2s.sacr0 = SACR0; - pxa_i2s.sacr1 = SACR1; - pxa_i2s.saimr = SAIMR; - pxa_i2s.sadiv = SADIV; - - /* deactivate link */ - SACR0 &= ~SACR0_ENB; - pxa_i2s_wait(); - return 0; -} - -static int pxa2xx_i2s_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *dai) -{ - if (!dai->active) - return 0; - - pxa_i2s_wait(); - - SACR0 = pxa_i2s.sacr0 &= ~SACR0_ENB; - SACR1 = pxa_i2s.sacr1; - SAIMR = pxa_i2s.saimr; - SADIV = pxa_i2s.sadiv; - SACR0 |= SACR0_ENB; - - return 0; -} - -#else -#define pxa2xx_i2s_suspend NULL -#define pxa2xx_i2s_resume NULL -#endif - -#define PXA2XX_I2S_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_96000) - -struct snd_soc_cpu_dai pxa_i2s_dai = { - .name = "pxa2xx-i2s", - .id = 0, - .type = SND_SOC_DAI_I2S, - .suspend = pxa2xx_i2s_suspend, - .resume = pxa2xx_i2s_resume, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = PXA2XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = PXA2XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .startup = pxa2xx_i2s_startup, - .shutdown = pxa2xx_i2s_shutdown, - .trigger = pxa2xx_i2s_trigger, - .hw_params = pxa2xx_i2s_hw_params,}, - .dai_ops = { - .set_fmt = pxa2xx_i2s_set_dai_fmt, - .set_sysclk = pxa2xx_i2s_set_dai_sysclk, - }, -}; - -EXPORT_SYMBOL_GPL(pxa_i2s_dai); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.h b/trunk/sound/soc/pxa/pxa2xx-i2s.h deleted file mode 100644 index a2484f0881f1..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-i2s.h - * - * 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 _PXA2XX_I2S_H -#define _PXA2XX_I2S_H - -/* pxa2xx DAI ID's */ -#define PXA2XX_DAI_I2S 0 - -/* I2S clock */ -#define PXA2XX_I2S_SYSCLK 0 - -extern struct snd_soc_cpu_dai pxa_i2s_dai; - -#endif diff --git a/trunk/sound/soc/pxa/pxa2xx-pcm.c b/trunk/sound/soc/pxa/pxa2xx-pcm.c deleted file mode 100644 index 35e8fa3a469c..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-pcm.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: (C) 2004 MontaVista Software, Inc. - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "pxa2xx-pcm.h" - -static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, - .period_bytes_min = 32, - .period_bytes_max = 8192 - 32, - .periods_min = 1, - .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), - .buffer_bytes_max = 128 * 1024, - .fifo_size = 32, -}; - -struct pxa2xx_runtime_data { - int dma_ch; - struct pxa2xx_pcm_dma_params *params; - pxa_dma_desc *dma_desc_array; - dma_addr_t dma_desc_array_phys; -}; - -static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) -{ - struct snd_pcm_substream *substream = dev_id; - struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; - int dcsr; - - dcsr = DCSR(dma_ch); - DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN; - - if (dcsr & DCSR_ENDINTR) { - snd_pcm_period_elapsed(substream); - } else { - printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", - prtd->params->name, dma_ch, dcsr ); - } -} - -static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct pxa2xx_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; - size_t totsize = params_buffer_bytes(params); - size_t period = params_period_bytes(params); - pxa_dma_desc *dma_desc; - dma_addr_t dma_buff_phys, next_desc_phys; - int ret; - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!dma) - return 0; - - /* this may get called several times by oss emulation - * with different params */ - if (prtd->params == NULL) { - prtd->params = dma; - ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW, - pxa2xx_pcm_dma_irq, substream); - if (ret < 0) - return ret; - prtd->dma_ch = ret; - } else if (prtd->params != dma) { - pxa_free_dma(prtd->dma_ch); - prtd->params = dma; - ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW, - pxa2xx_pcm_dma_irq, substream); - if (ret < 0) - return ret; - prtd->dma_ch = ret; - } - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = totsize; - - dma_desc = prtd->dma_desc_array; - next_desc_phys = prtd->dma_desc_array_phys; - dma_buff_phys = runtime->dma_addr; - do { - next_desc_phys += sizeof(pxa_dma_desc); - dma_desc->ddadr = next_desc_phys; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - dma_desc->dsadr = dma_buff_phys; - dma_desc->dtadr = prtd->params->dev_addr; - } else { - dma_desc->dsadr = prtd->params->dev_addr; - dma_desc->dtadr = dma_buff_phys; - } - if (period > totsize) - period = totsize; - dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN; - dma_desc++; - dma_buff_phys += period; - } while (totsize -= period); - dma_desc[-1].ddadr = prtd->dma_desc_array_phys; - - return 0; -} - -static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; - - if (prtd && prtd->params) - *prtd->params->drcmr = 0; - - if (prtd->dma_ch) { - snd_pcm_set_runtime_buffer(substream, NULL); - pxa_free_dma(prtd->dma_ch); - prtd->dma_ch = 0; - } - - return 0; -} - -static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; - - DCSR(prtd->dma_ch) &= ~DCSR_RUN; - DCSR(prtd->dma_ch) = 0; - DCMD(prtd->dma_ch) = 0; - *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD; - - return 0; -} - -static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys; - DCSR(prtd->dma_ch) = DCSR_RUN; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - DCSR(prtd->dma_ch) &= ~DCSR_RUN; - break; - - case SNDRV_PCM_TRIGGER_RESUME: - DCSR(prtd->dma_ch) |= DCSR_RUN; - break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys; - DCSR(prtd->dma_ch) |= DCSR_RUN; - break; - - default: - ret = -EINVAL; - } - - return ret; -} - -static snd_pcm_uframes_t -pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct pxa2xx_runtime_data *prtd = runtime->private_data; - - dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch); - snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr); - - if (x == runtime->buffer_size) - x = 0; - return x; -} - -static int pxa2xx_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct pxa2xx_runtime_data *prtd; - int ret; - - snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware); - - /* - * For mysterious reasons (and despite what the manual says) - * playback samples are lost if the DMA count is not a multiple - * of the DMA burst size. Let's add a rule to enforce that. - */ - ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); - if (ret) - goto out; - - ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); - if (ret) - goto out; - - ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - goto out; - - prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL); - if (prtd == NULL) { - ret = -ENOMEM; - goto out; - } - - prtd->dma_desc_array = - dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE, - &prtd->dma_desc_array_phys, GFP_KERNEL); - if (!prtd->dma_desc_array) { - ret = -ENOMEM; - goto err1; - } - - runtime->private_data = prtd; - return 0; - - err1: - kfree(prtd); - out: - return ret; -} - -static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct pxa2xx_runtime_data *prtd = runtime->private_data; - - dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, - prtd->dma_desc_array, prtd->dma_desc_array_phys); - kfree(prtd); - return 0; -} - -static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -struct snd_pcm_ops pxa2xx_pcm_ops = { - .open = pxa2xx_pcm_open, - .close = pxa2xx_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pxa2xx_pcm_hw_params, - .hw_free = pxa2xx_pcm_hw_free, - .prepare = pxa2xx_pcm_prepare, - .trigger = pxa2xx_pcm_trigger, - .pointer = pxa2xx_pcm_pointer, - .mmap = pxa2xx_pcm_mmap, -}; - -static int pxa2xx_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 = pxa2xx_pcm_hardware.buffer_bytes_max; - 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 pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - 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 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; - -int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, - struct snd_pcm *pcm) -{ - int ret = 0; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &pxa2xx_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_32BIT_MASK; - - if (dai->playback.channels_min) { - ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (dai->capture.channels_min) { - ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - out: - return ret; -} - -struct snd_soc_platform pxa2xx_soc_platform = { - .name = "pxa2xx-audio", - .pcm_ops = &pxa2xx_pcm_ops, - .pcm_new = pxa2xx_pcm_new, - .pcm_free = pxa2xx_pcm_free_dma_buffers, -}; - -EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); - -MODULE_AUTHOR("Nicolas Pitre"); -MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/pxa2xx-pcm.h b/trunk/sound/soc/pxa/pxa2xx-pcm.h deleted file mode 100644 index 54c9c755e508..000000000000 --- a/trunk/sound/soc/pxa/pxa2xx-pcm.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip - * - * Author: Nicolas Pitre - * Created: Nov 30, 2004 - * Copyright: MontaVista Software, Inc. - * - * 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 _PXA2XX_PCM_H -#define _PXA2XX_PCM_H - -struct pxa2xx_pcm_dma_params { - char *name; /* stream identifier */ - u32 dcmd; /* DMA descriptor dcmd field */ - volatile u32 *drcmr; /* the DMA request channel to use */ - u32 dev_addr; /* device physical address for DMA */ -}; - -struct pxa2xx_gpio { - u32 sys; - u32 rx; - u32 tx; - u32 clk; - u32 frm; -}; - -/* platform data */ -extern struct snd_soc_platform pxa2xx_soc_platform; - -#endif diff --git a/trunk/sound/soc/pxa/spitz.c b/trunk/sound/soc/pxa/spitz.c deleted file mode 100644 index 80e82109fef7..000000000000 --- a/trunk/sound/soc/pxa/spitz.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * spitz.c -- SoC audio for Sharp SL-Cxx00 models Spitz, Borzoi and Akita - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood - * Richard Purdie - * - * 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 - * 30th Nov 2005 Initial version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include "../codecs/wm8750.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-i2s.h" - -#define SPITZ_HP 0 -#define SPITZ_MIC 1 -#define SPITZ_LINE 2 -#define SPITZ_HEADSET 3 -#define SPITZ_HP_OFF 4 -#define SPITZ_SPK_ON 0 -#define SPITZ_SPK_OFF 1 - - /* audio clock in Hz - rounded from 12.235MHz */ -#define SPITZ_AUDIO_CLOCK 12288000 - -static int spitz_jack_func; -static int spitz_spk_func; - -static void spitz_ext_control(struct snd_soc_codec *codec) -{ - if (spitz_spk_func == SPITZ_SPK_ON) - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 1); - else - snd_soc_dapm_set_endpoint(codec, "Ext Spk", 0); - - /* set up jack connection */ - switch (spitz_jack_func) { - case SPITZ_HP: - /* enable and unmute hp jack, disable mic bias */ - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 1); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); - break; - case SPITZ_MIC: - /* enable mic jack and bias, mute hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); - break; - case SPITZ_LINE: - /* enable line jack, disable mic bias and mute hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 1); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); - break; - case SPITZ_HEADSET: - /* enable and unmute headset jack enable mic bias, mute L hp */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 1); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 1); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); - break; - case SPITZ_HP_OFF: - - /* jack removed, everything off */ - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Mic Jack", 0); - snd_soc_dapm_set_endpoint(codec, "Line Jack", 0); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); - break; - } - snd_soc_dapm_sync_endpoints(codec); -} - -static int spitz_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* check the jack status at stream startup */ - spitz_ext_control(codec); - return 0; -} - -static int spitz_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_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops spitz_ops = { - .startup = spitz_startup, - .hw_params = spitz_hw_params, -}; - -static int spitz_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spitz_jack_func; - return 0; -} - -static int spitz_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (spitz_jack_func == ucontrol->value.integer.value[0]) - return 0; - - spitz_jack_func = ucontrol->value.integer.value[0]; - spitz_ext_control(codec); - return 1; -} - -static int spitz_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spitz_spk_func; - return 0; -} - -static int spitz_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (spitz_spk_func == ucontrol->value.integer.value[0]) - return 0; - - spitz_spk_func = ucontrol->value.integer.value[0]; - spitz_ext_control(codec); - return 1; -} - -static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event) -{ - if (machine_is_borzoi() || machine_is_spitz()) { - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&spitzscoop2_device.dev, - SPITZ_SCP2_MIC_BIAS); - else - reset_scoop_gpio(&spitzscoop2_device.dev, - SPITZ_SCP2_MIC_BIAS); - } - - if (machine_is_akita()) { - if (SND_SOC_DAPM_EVENT_ON(event)) - akita_set_ioexp(&akitaioexp_device.dev, - AKITA_IOEXP_MIC_BIAS); - else - akita_reset_ioexp(&akitaioexp_device.dev, - AKITA_IOEXP_MIC_BIAS); - } - return 0; -} - -/* spitz machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_LINE("Line Jack", NULL), - - /* headset is a mic and mono headphone */ - SND_SOC_DAPM_HP("Headset Jack", NULL), -}; - -/* Spitz machine audio_map */ -static const char *audio_map[][3] = { - - /* headphone connected to LOUT1, ROUT1 */ - {"Headphone Jack", NULL, "LOUT1"}, - {"Headphone Jack", NULL, "ROUT1"}, - - /* headset connected to ROUT1 and LINPUT1 with bias (def below) */ - {"Headset Jack", NULL, "ROUT1"}, - - /* ext speaker connected to LOUT2, ROUT2 */ - {"Ext Spk", NULL , "ROUT2"}, - {"Ext Spk", NULL , "LOUT2"}, - - /* mic is connected to input 1 - with bias */ - {"LINPUT1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Mic Jack"}, - - /* line is connected to input 1 - no bias */ - {"LINPUT1", NULL, "Line Jack"}, - - {NULL, NULL, NULL}, -}; - -static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", - "Off"}; -static const char *spk_function[] = {"On", "Off"}; -static const struct soc_enum spitz_enum[] = { - SOC_ENUM_SINGLE_EXT(5, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new wm8750_spitz_controls[] = { - SOC_ENUM_EXT("Jack Function", spitz_enum[0], spitz_get_jack, - spitz_set_jack), - SOC_ENUM_EXT("Speaker Function", spitz_enum[1], spitz_get_spk, - spitz_set_spk), -}; - -/* - * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device - */ -static int spitz_wm8750_init(struct snd_soc_codec *codec) -{ - int i, err; - - /* NC codec pins */ - snd_soc_dapm_set_endpoint(codec, "RINPUT1", 0); - snd_soc_dapm_set_endpoint(codec, "LINPUT2", 0); - snd_soc_dapm_set_endpoint(codec, "RINPUT2", 0); - snd_soc_dapm_set_endpoint(codec, "LINPUT3", 0); - snd_soc_dapm_set_endpoint(codec, "RINPUT3", 0); - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "MONO", 0); - - /* Add spitz specific controls */ - for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8750_spitz_controls[i], codec, NULL)); - if (err < 0) - return err; - } - - /* Add spitz specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); - } - - /* Set up spitz specific audio path 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_sync_endpoints(codec); - return 0; -} - -/* spitz digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link spitz_dai = { - .name = "wm8750", - .stream_name = "WM8750", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8750_dai, - .init = spitz_wm8750_init, - .ops = &spitz_ops, -}; - -/* spitz audio machine driver */ -static struct snd_soc_machine snd_soc_machine_spitz = { - .name = "Spitz", - .dai_link = &spitz_dai, - .num_links = 1, -}; - -/* spitz audio private data */ -static struct wm8750_setup_data spitz_wm8750_setup = { - .i2c_address = 0x1b, -}; - -/* spitz audio subsystem */ -static struct snd_soc_device spitz_snd_devdata = { - .machine = &snd_soc_machine_spitz, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8750, - .codec_data = &spitz_wm8750_setup, -}; - -static struct platform_device *spitz_snd_device; - -static int __init spitz_init(void) -{ - int ret; - - if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) - return -ENODEV; - - spitz_snd_device = platform_device_alloc("soc-audio", -1); - if (!spitz_snd_device) - return -ENOMEM; - - platform_set_drvdata(spitz_snd_device, &spitz_snd_devdata); - spitz_snd_devdata.dev = &spitz_snd_device->dev; - ret = platform_device_add(spitz_snd_device); - - if (ret) - platform_device_put(spitz_snd_device); - - return ret; -} - -static void __exit spitz_exit(void) -{ - platform_device_unregister(spitz_snd_device); -} - -module_init(spitz_init); -module_exit(spitz_exit); - -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Spitz"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/tosa.c b/trunk/sound/soc/pxa/tosa.c deleted file mode 100644 index 5504e30acf14..000000000000 --- a/trunk/sound/soc/pxa/tosa.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * tosa.c -- SoC audio for Tosa - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood - * Richard Purdie - * - * 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 - * 30th Nov 2005 Initial version. - * - * GPIO's - * 1 - Jack Insertion - * 5 - Hookswitch (headset answer/hang up switch) - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "../codecs/wm9712.h" -#include "pxa2xx-pcm.h" -#include "pxa2xx-ac97.h" - -static struct snd_soc_machine tosa; - -#define TOSA_HP 0 -#define TOSA_MIC_INT 1 -#define TOSA_HEADSET 2 -#define TOSA_HP_OFF 3 -#define TOSA_SPK_ON 0 -#define TOSA_SPK_OFF 1 - -static int tosa_jack_func; -static int tosa_spk_func; - -static void tosa_ext_control(struct snd_soc_codec *codec) -{ - int spk = 0, mic_int = 0, hp = 0, hs = 0; - - /* set up jack connection */ - switch (tosa_jack_func) { - case TOSA_HP: - hp = 1; - break; - case TOSA_MIC_INT: - mic_int = 1; - break; - case TOSA_HEADSET: - hs = 1; - break; - } - - if (tosa_spk_func == TOSA_SPK_ON) - spk = 1; - - snd_soc_dapm_set_endpoint(codec, "Speaker", spk); - snd_soc_dapm_set_endpoint(codec, "Mic (Internal)", mic_int); - snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp); - snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs); - snd_soc_dapm_sync_endpoints(codec); -} - -static int tosa_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - - /* check the jack status at stream startup */ - tosa_ext_control(codec); - return 0; -} - -static struct snd_soc_ops tosa_ops = { - .startup = tosa_startup, -}; - -static int tosa_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = tosa_jack_func; - return 0; -} - -static int tosa_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (tosa_jack_func == ucontrol->value.integer.value[0]) - return 0; - - tosa_jack_func = ucontrol->value.integer.value[0]; - tosa_ext_control(codec); - return 1; -} - -static int tosa_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = tosa_spk_func; - return 0; -} - -static int tosa_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (tosa_spk_func == ucontrol->value.integer.value[0]) - return 0; - - tosa_spk_func = ucontrol->value.integer.value[0]; - tosa_ext_control(codec); - return 1; -} - -/* tosa dapm event handlers */ -static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); - else - reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); - return 0; -} - -/* tosa machine dapm widgets */ -static const struct snd_soc_dapm_widget tosa_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", tosa_hp_event), -SND_SOC_DAPM_HP("Headset Jack", NULL), -SND_SOC_DAPM_MIC("Mic (Internal)", NULL), -SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* tosa audio map */ -static const char *audio_map[][3] = { - - /* headphone connected to HPOUTL, HPOUTR */ - {"Headphone Jack", NULL, "HPOUTL"}, - {"Headphone Jack", NULL, "HPOUTR"}, - - /* ext speaker connected to LOUT2, ROUT2 */ - {"Speaker", NULL, "LOUT2"}, - {"Speaker", NULL, "ROUT2"}, - - /* internal mic is connected to mic1, mic2 differential - with bias */ - {"MIC1", NULL, "Mic Bias"}, - {"MIC2", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Mic (Internal)"}, - - /* headset is connected to HPOUTR, and LINEINR with bias */ - {"Headset Jack", NULL, "HPOUTR"}, - {"LINEINR", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Jack"}, - - {NULL, NULL, NULL}, -}; - -static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset", - "Off"}; -static const char *spk_function[] = {"On", "Off"}; -static const struct soc_enum tosa_enum[] = { - SOC_ENUM_SINGLE_EXT(5, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new tosa_controls[] = { - SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack, - tosa_set_jack), - SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk, - tosa_set_spk), -}; - -static int tosa_ac97_init(struct snd_soc_codec *codec) -{ - int i, err; - - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "MONOOUT", 0); - - /* add tosa specific controls */ - for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&tosa_controls[i],codec, NULL)); - if (err < 0) - return err; - } - - /* add tosa specific widgets */ - for (i = 0; i < ARRAY_SIZE(tosa_dapm_widgets); i++) { - snd_soc_dapm_new_control(codec, &tosa_dapm_widgets[i]); - } - - /* set up tosa specific audio path 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_sync_endpoints(codec); - return 0; -} - -static struct snd_soc_dai_link tosa_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], - .init = tosa_ac97_init, - .ops = &tosa_ops, -}, -{ - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], - .ops = &tosa_ops, -}, -}; - -static struct snd_soc_machine tosa = { - .name = "Tosa", - .dai_link = tosa_dai, - .num_links = ARRAY_SIZE(tosa_dai), -}; - -static struct snd_soc_device tosa_snd_devdata = { - .machine = &tosa, - .platform = &pxa2xx_soc_platform, - .codec_dev = &soc_codec_dev_wm9712, -}; - -static struct platform_device *tosa_snd_device; - -static int __init tosa_init(void) -{ - int ret; - - if (!machine_is_tosa()) - return -ENODEV; - - tosa_snd_device = platform_device_alloc("soc-audio", -1); - if (!tosa_snd_device) - return -ENOMEM; - - platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata); - tosa_snd_devdata.dev = &tosa_snd_device->dev; - ret = platform_device_add(tosa_snd_device); - - if (ret) - platform_device_put(tosa_snd_device); - - return ret; -} - -static void __exit tosa_exit(void) -{ - platform_device_unregister(tosa_snd_device); -} - -module_init(tosa_init); -module_exit(tosa_exit); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Tosa"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c deleted file mode 100644 index 36519aef55d9..000000000000 --- a/trunk/sound/soc/soc-core.c +++ /dev/null @@ -1,1587 +0,0 @@ -/* - * soc-core.c -- ALSA SoC Audio Layer - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Author: Liam Girdwood - * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com - * with code, comments and ideas from :- - * Richard Purdie - * - * 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 - * 12th Aug 2005 Initial version. - * 25th Oct 2005 Working Codec, Interface and Platform registration. - * - * TODO: - * o Add hw rules to enforce rates, etc. - * o More testing with other codecs/machines. - * o Add more codecs and platforms to ensure good API coverage. - * o Support TDM on PCM and I2S - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug */ -#define SOC_DEBUG 0 -#if SOC_DEBUG -#define dbg(format, arg...) printk(format, ## arg) -#else -#define dbg(format, arg...) -#endif - -static DEFINE_MUTEX(pcm_mutex); -static DEFINE_MUTEX(io_mutex); -static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); - -/* - * This is a timeout to do a DAPM powerdown after a stream is closed(). - * It can be used to eliminate pops between different playback streams, e.g. - * between two audio tracks. - */ -static int pmdown_time = 5000; -module_param(pmdown_time, int, 0); -MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); - -/* - * 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; -} - -#ifdef CONFIG_SND_SOC_AC97_BUS -/* unregister ac97 codec */ -static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) -{ - if (codec->ac97->dev.bus) - device_unregister(&codec->ac97->dev); - return 0; -} - -/* stop no dev release warning */ -static void soc_ac97_device_release(struct device *dev){} - -/* register ac97 codec to bus */ -static int soc_ac97_dev_register(struct snd_soc_codec *codec) -{ - int err; - - codec->ac97->dev.bus = &ac97_bus_type; - codec->ac97->dev.parent = NULL; - codec->ac97->dev.release = soc_ac97_device_release; - - snprintf(codec->ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s", - codec->card->number, 0, codec->name); - err = device_register(&codec->ac97->dev); - if (err < 0) { - snd_printk(KERN_ERR "Can't register ac97 bus\n"); - codec->ac97->dev.bus = NULL; - return err; - } - return 0; -} -#endif - -static inline const char* get_dai_name(int type) -{ - switch(type) { - case SND_SOC_DAI_AC97: - return "AC97"; - case SND_SOC_DAI_I2S: - return "I2S"; - case SND_SOC_DAI_PCM: - return "PCM"; - } - return NULL; -} - -/* - * Called by ALSA when a PCM substream is opened, the runtime->hw record is - * then initialized and any private data can be allocated. This also calls - * startup for the cpu DAI, platform, machine and codec DAI. - */ -static int soc_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - int ret = 0; - - mutex_lock(&pcm_mutex); - - /* startup the audio subsystem */ - if (cpu_dai->ops.startup) { - ret = cpu_dai->ops.startup(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: can't open interface %s\n", - cpu_dai->name); - goto out; - } - } - - if (platform->pcm_ops->open) { - ret = platform->pcm_ops->open(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); - goto platform_err; - } - } - - if (codec_dai->ops.startup) { - ret = codec_dai->ops.startup(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: can't open codec %s\n", - codec_dai->name); - goto codec_dai_err; - } - } - - if (machine->ops && machine->ops->startup) { - ret = machine->ops->startup(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: %s startup failed\n", machine->name); - goto machine_err; - } - } - - /* Check that the codec and cpu DAI's are compatible */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - runtime->hw.rate_min = - max(codec_dai->playback.rate_min, cpu_dai->playback.rate_min); - runtime->hw.rate_max = - min(codec_dai->playback.rate_max, cpu_dai->playback.rate_max); - runtime->hw.channels_min = - max(codec_dai->playback.channels_min, - cpu_dai->playback.channels_min); - runtime->hw.channels_max = - min(codec_dai->playback.channels_max, - cpu_dai->playback.channels_max); - runtime->hw.formats = - codec_dai->playback.formats & cpu_dai->playback.formats; - runtime->hw.rates = - codec_dai->playback.rates & cpu_dai->playback.rates; - } else { - runtime->hw.rate_min = - max(codec_dai->capture.rate_min, cpu_dai->capture.rate_min); - runtime->hw.rate_max = - min(codec_dai->capture.rate_max, cpu_dai->capture.rate_max); - runtime->hw.channels_min = - max(codec_dai->capture.channels_min, - cpu_dai->capture.channels_min); - runtime->hw.channels_max = - min(codec_dai->capture.channels_max, - cpu_dai->capture.channels_max); - runtime->hw.formats = - codec_dai->capture.formats & cpu_dai->capture.formats; - runtime->hw.rates = - codec_dai->capture.rates & cpu_dai->capture.rates; - } - - snd_pcm_limit_hw_rates(runtime); - if (!runtime->hw.rates) { - printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", - codec_dai->name, cpu_dai->name); - goto machine_err; - } - if (!runtime->hw.formats) { - printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", - codec_dai->name, cpu_dai->name); - goto machine_err; - } - if (!runtime->hw.channels_min || !runtime->hw.channels_max) { - printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", - codec_dai->name, cpu_dai->name); - goto machine_err; - } - - dbg("asoc: %s <-> %s info:\n",codec_dai->name, cpu_dai->name); - dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); - dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, - runtime->hw.channels_max); - dbg("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, - runtime->hw.rate_max); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->playback.active = codec_dai->playback.active = 1; - else - cpu_dai->capture.active = codec_dai->capture.active = 1; - cpu_dai->active = codec_dai->active = 1; - cpu_dai->runtime = runtime; - socdev->codec->active++; - mutex_unlock(&pcm_mutex); - return 0; - -machine_err: - if (machine->ops && machine->ops->shutdown) - machine->ops->shutdown(substream); - -codec_dai_err: - if (platform->pcm_ops->close) - platform->pcm_ops->close(substream); - -platform_err: - if (cpu_dai->ops.shutdown) - cpu_dai->ops.shutdown(substream); -out: - mutex_unlock(&pcm_mutex); - return ret; -} - -/* - * Power down the audio subsytem pmdown_time msecs after close is called. - * This is to ensure there are no pops or clicks in between any music tracks - * due to DAPM power cycling. - */ -static void close_delayed_work(struct work_struct *work) -{ - struct snd_soc_device *socdev = - container_of(work, struct snd_soc_device, delayed_work.work); - struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_codec_dai *codec_dai; - int i; - - mutex_lock(&pcm_mutex); - for(i = 0; i < codec->num_dai; i++) { - codec_dai = &codec->dai[i]; - - dbg("pop wq checking: %s status: %s waiting: %s\n", - codec_dai->playback.stream_name, - codec_dai->playback.active ? "active" : "inactive", - codec_dai->pop_wait ? "yes" : "no"); - - /* are we waiting on this codec DAI stream */ - if (codec_dai->pop_wait == 1) { - - codec_dai->pop_wait = 0; - snd_soc_dapm_stream_event(codec, codec_dai->playback.stream_name, - SND_SOC_DAPM_STREAM_STOP); - - /* power down the codec power domain if no longer active */ - if (codec->active == 0) { - dbg("pop wq D3 %s %s\n", codec->name, - codec_dai->playback.stream_name); - if (codec->dapm_event) - codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot); - } - } - } - mutex_unlock(&pcm_mutex); -} - -/* - * Called by ALSA when a PCM substream is closed. Private data can be - * freed here. The cpu DAI, codec DAI, machine and platform are also - * shutdown. - */ -static int soc_codec_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = socdev->codec; - - mutex_lock(&pcm_mutex); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->playback.active = codec_dai->playback.active = 0; - else - cpu_dai->capture.active = codec_dai->capture.active = 0; - - if (codec_dai->playback.active == 0 && - codec_dai->capture.active == 0) { - cpu_dai->active = codec_dai->active = 0; - } - codec->active--; - - if (cpu_dai->ops.shutdown) - cpu_dai->ops.shutdown(substream); - - if (codec_dai->ops.shutdown) - codec_dai->ops.shutdown(substream); - - if (machine->ops && machine->ops->shutdown) - machine->ops->shutdown(substream); - - if (platform->pcm_ops->close) - platform->pcm_ops->close(substream); - cpu_dai->runtime = NULL; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /* start delayed pop wq here for playback streams */ - codec_dai->pop_wait = 1; - schedule_delayed_work(&socdev->delayed_work, - msecs_to_jiffies(pmdown_time)); - } else { - /* capture streams can be powered down now */ - snd_soc_dapm_stream_event(codec, - codec_dai->capture.stream_name, SND_SOC_DAPM_STREAM_STOP); - - if (codec->active == 0 && codec_dai->pop_wait == 0){ - if (codec->dapm_event) - codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot); - } - } - - mutex_unlock(&pcm_mutex); - return 0; -} - -/* - * Called by ALSA when the PCM substream is prepared, can set format, sample - * rate, etc. This function is non atomic and can be called multiple times, - * it can refer to the runtime info. - */ -static int soc_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = socdev->codec; - int ret = 0; - - mutex_lock(&pcm_mutex); - - if (machine->ops && machine->ops->prepare) { - ret = machine->ops->prepare(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: machine prepare error\n"); - goto out; - } - } - - if (platform->pcm_ops->prepare) { - ret = platform->pcm_ops->prepare(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: platform prepare error\n"); - goto out; - } - } - - if (codec_dai->ops.prepare) { - ret = codec_dai->ops.prepare(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: codec DAI prepare error\n"); - goto out; - } - } - - if (cpu_dai->ops.prepare) { - ret = cpu_dai->ops.prepare(substream); - if (ret < 0) { - printk(KERN_ERR "asoc: cpu DAI prepare error\n"); - goto out; - } - } - - /* we only want to start a DAPM playback stream if we are not waiting - * on an existing one stopping */ - if (codec_dai->pop_wait) { - /* we are waiting for the delayed work to start */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - snd_soc_dapm_stream_event(socdev->codec, - codec_dai->capture.stream_name, - SND_SOC_DAPM_STREAM_START); - else { - codec_dai->pop_wait = 0; - cancel_delayed_work(&socdev->delayed_work); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); - } - } else { - /* no delayed work - do we need to power up codec */ - if (codec->dapm_state != SNDRV_CTL_POWER_D0) { - - if (codec->dapm_event) - codec->dapm_event(codec, SNDRV_CTL_POWER_D1); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_dapm_stream_event(codec, - codec_dai->playback.stream_name, - SND_SOC_DAPM_STREAM_START); - else - snd_soc_dapm_stream_event(codec, - codec_dai->capture.stream_name, - SND_SOC_DAPM_STREAM_START); - - if (codec->dapm_event) - codec->dapm_event(codec, SNDRV_CTL_POWER_D0); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); - - } else { - /* codec already powered - power on widgets */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_dapm_stream_event(codec, - codec_dai->playback.stream_name, - SND_SOC_DAPM_STREAM_START); - else - snd_soc_dapm_stream_event(codec, - codec_dai->capture.stream_name, - SND_SOC_DAPM_STREAM_START); - if (codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 0); - } - } - -out: - mutex_unlock(&pcm_mutex); - return ret; -} - -/* - * Called by ALSA when the hardware params are set by application. This - * function can also be called multiple times and can allocate buffers - * (using snd_pcm_lib_* ). It's non-atomic. - */ -static int soc_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_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - int ret = 0; - - mutex_lock(&pcm_mutex); - - if (machine->ops && machine->ops->hw_params) { - ret = machine->ops->hw_params(substream, params); - if (ret < 0) { - printk(KERN_ERR "asoc: machine hw_params failed\n"); - goto out; - } - } - - if (codec_dai->ops.hw_params) { - ret = codec_dai->ops.hw_params(substream, params); - if (ret < 0) { - printk(KERN_ERR "asoc: can't set codec %s hw params\n", - codec_dai->name); - goto codec_err; - } - } - - if (cpu_dai->ops.hw_params) { - ret = cpu_dai->ops.hw_params(substream, params); - if (ret < 0) { - printk(KERN_ERR "asoc: can't set interface %s hw params\n", - cpu_dai->name); - goto interface_err; - } - } - - if (platform->pcm_ops->hw_params) { - ret = platform->pcm_ops->hw_params(substream, params); - if (ret < 0) { - printk(KERN_ERR "asoc: can't set platform %s hw params\n", - platform->name); - goto platform_err; - } - } - -out: - mutex_unlock(&pcm_mutex); - return ret; - -platform_err: - if (cpu_dai->ops.hw_free) - cpu_dai->ops.hw_free(substream); - -interface_err: - if (codec_dai->ops.hw_free) - codec_dai->ops.hw_free(substream); - -codec_err: - if(machine->ops && machine->ops->hw_free) - machine->ops->hw_free(substream); - - mutex_unlock(&pcm_mutex); - return ret; -} - -/* - * Free's resources allocated by hw_params, can be called multiple times - */ -static int soc_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - struct snd_soc_codec *codec = socdev->codec; - - mutex_lock(&pcm_mutex); - - /* apply codec digital mute */ - if (!codec->active && codec_dai->dai_ops.digital_mute) - codec_dai->dai_ops.digital_mute(codec_dai, 1); - - /* free any machine hw params */ - if (machine->ops && machine->ops->hw_free) - machine->ops->hw_free(substream); - - /* free any DMA resources */ - if (platform->pcm_ops->hw_free) - platform->pcm_ops->hw_free(substream); - - /* now free hw params for the DAI's */ - if (codec_dai->ops.hw_free) - codec_dai->ops.hw_free(substream); - - if (cpu_dai->ops.hw_free) - cpu_dai->ops.hw_free(substream); - - mutex_unlock(&pcm_mutex); - return 0; -} - -static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_device *socdev = rtd->socdev; - struct snd_soc_dai_link *machine = rtd->dai; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_cpu_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_codec_dai *codec_dai = machine->codec_dai; - int ret; - - if (codec_dai->ops.trigger) { - ret = codec_dai->ops.trigger(substream, cmd); - if (ret < 0) - return ret; - } - - if (platform->pcm_ops->trigger) { - ret = platform->pcm_ops->trigger(substream, cmd); - if (ret < 0) - return ret; - } - - if (cpu_dai->ops.trigger) { - ret = cpu_dai->ops.trigger(substream, cmd); - if (ret < 0) - return ret; - } - return 0; -} - -/* ASoC PCM operations */ -static struct snd_pcm_ops soc_pcm_ops = { - .open = soc_pcm_open, - .close = soc_codec_close, - .hw_params = soc_pcm_hw_params, - .hw_free = soc_pcm_hw_free, - .prepare = soc_pcm_prepare, - .trigger = soc_pcm_trigger, -}; - -#ifdef CONFIG_PM -/* powers down audio subsystem for suspend */ -static int soc_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - struct snd_soc_codec *codec = socdev->codec; - int i; - - /* mute any active DAC's */ - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; - if (dai->dai_ops.digital_mute && dai->playback.active) - dai->dai_ops.digital_mute(dai, 1); - } - - if (machine->suspend_pre) - machine->suspend_pre(pdev, state); - - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) - cpu_dai->suspend(pdev, cpu_dai); - if (platform->suspend) - platform->suspend(pdev, cpu_dai); - } - - /* close any waiting streams and save state */ - run_delayed_work(&socdev->delayed_work); - codec->suspend_dapm_state = codec->dapm_state; - - for(i = 0; i < codec->num_dai; i++) { - char *stream = codec->dai[i].playback.stream_name; - if (stream != NULL) - snd_soc_dapm_stream_event(codec, stream, - SND_SOC_DAPM_STREAM_SUSPEND); - stream = codec->dai[i].capture.stream_name; - if (stream != NULL) - snd_soc_dapm_stream_event(codec, stream, - SND_SOC_DAPM_STREAM_SUSPEND); - } - - if (codec_dev->suspend) - codec_dev->suspend(pdev, state); - - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) - cpu_dai->suspend(pdev, cpu_dai); - } - - if (machine->suspend_post) - machine->suspend_post(pdev, state); - - return 0; -} - -/* powers up audio subsystem after a suspend */ -static int soc_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - struct snd_soc_codec *codec = socdev->codec; - int i; - - if (machine->resume_pre) - machine->resume_pre(pdev); - - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) - cpu_dai->resume(pdev, cpu_dai); - } - - if (codec_dev->resume) - codec_dev->resume(pdev); - - for(i = 0; i < codec->num_dai; i++) { - char* stream = codec->dai[i].playback.stream_name; - if (stream != NULL) - snd_soc_dapm_stream_event(codec, stream, - SND_SOC_DAPM_STREAM_RESUME); - stream = codec->dai[i].capture.stream_name; - if (stream != NULL) - snd_soc_dapm_stream_event(codec, stream, - SND_SOC_DAPM_STREAM_RESUME); - } - - /* unmute any active DAC's */ - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai; - if (dai->dai_ops.digital_mute && dai->playback.active) - dai->dai_ops.digital_mute(dai, 0); - } - - for(i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) - cpu_dai->resume(pdev, cpu_dai); - if (platform->resume) - platform->resume(pdev, cpu_dai); - } - - if (machine->resume_post) - machine->resume_post(pdev); - - return 0; -} - -#else -#define soc_suspend NULL -#define soc_resume NULL -#endif - -/* probes a new socdev */ -static int soc_probe(struct platform_device *pdev) -{ - int ret = 0, i; - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - - if (machine->probe) { - ret = machine->probe(pdev); - if(ret < 0) - return ret; - } - - for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->probe) { - ret = cpu_dai->probe(pdev); - if(ret < 0) - goto cpu_dai_err; - } - } - - if (codec_dev->probe) { - ret = codec_dev->probe(pdev); - if(ret < 0) - goto cpu_dai_err; - } - - if (platform->probe) { - ret = platform->probe(pdev); - if(ret < 0) - goto platform_err; - } - - /* DAPM stream work */ - INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); - return 0; - -platform_err: - if (codec_dev->remove) - codec_dev->remove(pdev); - -cpu_dai_err: - for (i--; i >= 0; i--) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->remove) - cpu_dai->remove(pdev); - } - - if (machine->remove) - machine->remove(pdev); - - return ret; -} - -/* removes a socdev */ -static int soc_remove(struct platform_device *pdev) -{ - int i; - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_machine *machine = socdev->machine; - struct snd_soc_platform *platform = socdev->platform; - struct snd_soc_codec_device *codec_dev = socdev->codec_dev; - - run_delayed_work(&socdev->delayed_work); - - if (platform->remove) - platform->remove(pdev); - - if (codec_dev->remove) - codec_dev->remove(pdev); - - for (i = 0; i < machine->num_links; i++) { - struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai; - if (cpu_dai->remove) - cpu_dai->remove(pdev); - } - - if (machine->remove) - machine->remove(pdev); - - return 0; -} - -/* ASoC platform driver */ -static struct platform_driver soc_driver = { - .driver = { - .name = "soc-audio", - }, - .probe = soc_probe, - .remove = soc_remove, - .suspend = soc_suspend, - .resume = soc_resume, -}; - -/* create a new pcm */ -static int soc_new_pcm(struct snd_soc_device *socdev, - struct snd_soc_dai_link *dai_link, int num) -{ - struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_codec_dai *codec_dai = dai_link->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = dai_link->cpu_dai; - struct snd_soc_pcm_runtime *rtd; - struct snd_pcm *pcm; - char new_name[64]; - int ret = 0, playback = 0, capture = 0; - - rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL); - if (rtd == NULL) - return -ENOMEM; - - rtd->dai = dai_link; - rtd->socdev = socdev; - codec_dai->codec = socdev->codec; - - /* check client and interface hw capabilities */ - sprintf(new_name, "%s %s-%s-%d",dai_link->stream_name, codec_dai->name, - get_dai_name(cpu_dai->type), num); - - if (codec_dai->playback.channels_min) - playback = 1; - if (codec_dai->capture.channels_min) - capture = 1; - - ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback, - capture, &pcm); - if (ret < 0) { - printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); - kfree(rtd); - return ret; - } - - pcm->private_data = rtd; - soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap; - soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer; - soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl; - soc_pcm_ops.copy = socdev->platform->pcm_ops->copy; - soc_pcm_ops.silence = socdev->platform->pcm_ops->silence; - soc_pcm_ops.ack = socdev->platform->pcm_ops->ack; - soc_pcm_ops.page = socdev->platform->pcm_ops->page; - - if (playback) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); - - if (capture) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); - - ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm); - if (ret < 0) { - printk(KERN_ERR "asoc: platform pcm constructor failed\n"); - kfree(rtd); - return ret; - } - - pcm->private_free = socdev->platform->pcm_free; - printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, - cpu_dai->name); - return ret; -} - -/* codec register dump */ -static ssize_t codec_reg_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct snd_soc_device *devdata = dev_get_drvdata(dev); - struct snd_soc_codec *codec = devdata->codec; - int i, step = 1, count = 0; - - if (!codec->reg_cache_size) - return 0; - - if (codec->reg_cache_step) - step = codec->reg_cache_step; - - count += sprintf(buf, "%s registers\n", codec->name); - for(i = 0; i < codec->reg_cache_size; i += step) - count += sprintf(buf + count, "%2x: %4x\n", i, codec->read(codec, i)); - - return count; -} -static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); - -/** - * snd_soc_new_ac97_codec - initailise AC97 device - * @codec: audio codec - * @ops: AC97 bus operations - * @num: AC97 codec number - * - * Initialises AC97 codec resources for use by ad-hoc devices only. - */ -int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, - struct snd_ac97_bus_ops *ops, int num) -{ - mutex_lock(&codec->mutex); - - codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); - if (codec->ac97 == NULL) { - mutex_unlock(&codec->mutex); - return -ENOMEM; - } - - codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL); - if (codec->ac97->bus == NULL) { - kfree(codec->ac97); - codec->ac97 = NULL; - mutex_unlock(&codec->mutex); - return -ENOMEM; - } - - codec->ac97->bus->ops = ops; - codec->ac97->num = num; - mutex_unlock(&codec->mutex); - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); - -/** - * snd_soc_free_ac97_codec - free AC97 codec device - * @codec: audio codec - * - * Frees AC97 codec device resources. - */ -void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) -{ - mutex_lock(&codec->mutex); - kfree(codec->ac97->bus); - kfree(codec->ac97); - codec->ac97 = NULL; - mutex_unlock(&codec->mutex); -} -EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); - -/** - * snd_soc_update_bits - update codec register bits - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Writes new register value. - * - * Returns 1 for change else 0. - */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned short mask, unsigned short value) -{ - int change; - unsigned short old, new; - - mutex_lock(&io_mutex); - old = snd_soc_read(codec, reg); - new = (old & ~mask) | value; - change = old != new; - if (change) - snd_soc_write(codec, reg, new); - - mutex_unlock(&io_mutex); - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_update_bits); - -/** - * snd_soc_test_bits - test register for change - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Tests a register with a new value and checks if the new value is - * different from the old value. - * - * Returns 1 for change else 0. - */ -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned short mask, unsigned short value) -{ - int change; - unsigned short old, new; - - mutex_lock(&io_mutex); - old = snd_soc_read(codec, reg); - new = (old & ~mask) | value; - change = old != new; - mutex_unlock(&io_mutex); - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_test_bits); - -/** - * snd_soc_new_pcms - create new sound card and pcms - * @socdev: the SoC audio device - * - * Create a new sound card based upon the codec and interface pcms. - * - * Returns 0 for success, else error. - */ -int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) -{ - struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_machine *machine = socdev->machine; - int ret = 0, i; - - mutex_lock(&codec->mutex); - - /* register a sound card */ - codec->card = snd_card_new(idx, xid, codec->owner, 0); - if (!codec->card) { - printk(KERN_ERR "asoc: can't create sound card for codec %s\n", - codec->name); - mutex_unlock(&codec->mutex); - return -ENODEV; - } - - codec->card->dev = socdev->dev; - codec->card->private_data = codec; - strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); - - /* create the pcms */ - for(i = 0; i < machine->num_links; i++) { - ret = soc_new_pcm(socdev, &machine->dai_link[i], i); - if (ret < 0) { - printk(KERN_ERR "asoc: can't create pcm %s\n", - machine->dai_link[i].stream_name); - mutex_unlock(&codec->mutex); - return ret; - } - } - - mutex_unlock(&codec->mutex); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_new_pcms); - -/** - * snd_soc_register_card - register sound card - * @socdev: the SoC audio device - * - * Register a SoC sound card. Also registers an AC97 device if the - * codec is AC97 for ad hoc devices. - * - * Returns 0 for success, else error. - */ -int snd_soc_register_card(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev->codec; - struct snd_soc_machine *machine = socdev->machine; - int ret = 0, i, ac97 = 0, err = 0; - - mutex_lock(&codec->mutex); - for(i = 0; i < machine->num_links; i++) { - if (socdev->machine->dai_link[i].init) { - err = socdev->machine->dai_link[i].init(codec); - if (err < 0) { - printk(KERN_ERR "asoc: failed to init %s\n", - socdev->machine->dai_link[i].stream_name); - continue; - } - } - if (socdev->machine->dai_link[i].cpu_dai->type == SND_SOC_DAI_AC97) - ac97 = 1; - } - snprintf(codec->card->shortname, sizeof(codec->card->shortname), - "%s", machine->name); - snprintf(codec->card->longname, sizeof(codec->card->longname), - "%s (%s)", machine->name, codec->name); - - ret = snd_card_register(codec->card); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to register soundcard for codec %s\n", - codec->name); - goto out; - } - -#ifdef CONFIG_SND_SOC_AC97_BUS - if (ac97) { - ret = soc_ac97_dev_register(codec); - if (ret < 0) { - printk(KERN_ERR "asoc: AC97 device register failed\n"); - snd_card_free(codec->card); - goto out; - } - } -#endif - - err = snd_soc_dapm_sys_add(socdev->dev); - if (err < 0) - printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n"); - - err = device_create_file(socdev->dev, &dev_attr_codec_reg); - if (err < 0) - printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n"); -out: - mutex_unlock(&codec->mutex); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_register_card); - -/** - * snd_soc_free_pcms - free sound card and pcms - * @socdev: the SoC audio device - * - * Frees sound card and pcms associated with the socdev. - * Also unregister the codec if it is an AC97 device. - */ -void snd_soc_free_pcms(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev->codec; - - mutex_lock(&codec->mutex); -#ifdef CONFIG_SND_SOC_AC97_BUS - if (codec->ac97) - soc_ac97_dev_unregister(codec); -#endif - - if (codec->card) - snd_card_free(codec->card); - device_remove_file(socdev->dev, &dev_attr_codec_reg); - mutex_unlock(&codec->mutex); -} -EXPORT_SYMBOL_GPL(snd_soc_free_pcms); - -/** - * snd_soc_set_runtime_hwparams - set the runtime hardware parameters - * @substream: the pcm substream - * @hw: the hardware parameters - * - * Sets the substream runtime hardware parameters. - */ -int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, - const struct snd_pcm_hardware *hw) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - runtime->hw.info = hw->info; - runtime->hw.formats = hw->formats; - runtime->hw.period_bytes_min = hw->period_bytes_min; - runtime->hw.period_bytes_max = hw->period_bytes_max; - runtime->hw.periods_min = hw->periods_min; - runtime->hw.periods_max = hw->periods_max; - runtime->hw.buffer_bytes_max = hw->buffer_bytes_max; - runtime->hw.fifo_size = hw->fifo_size; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams); - -/** - * snd_soc_cnew - create new control - * @_template: control template - * @data: control private data - * @lnng_name: control long name - * - * Create a new mixer control from a template control. - * - * Returns 0 for success, else error. - */ -struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, - void *data, char *long_name) -{ - struct snd_kcontrol_new template; - - memcpy(&template, _template, sizeof(template)); - if (long_name) - template.name = long_name; - template.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; - template.index = 0; - - return snd_ctl_new1(&template, data); -} -EXPORT_SYMBOL_GPL(snd_soc_cnew); - -/** - * snd_soc_info_enum_double - enumerated double mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a double enumerated - * mixer control. - * - * Returns 0 for success. - */ -int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = e->shift_l == e->shift_r ? 1 : 2; - uinfo->value.enumerated.items = e->mask; - - if (uinfo->value.enumerated.item > e->mask - 1) - uinfo->value.enumerated.item = e->mask - 1; - strcpy(uinfo->value.enumerated.name, - e->texts[uinfo->value.enumerated.item]); - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); - -/** - * snd_soc_get_enum_double - enumerated double mixer get callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to get the value of a double enumerated mixer. - * - * Returns 0 for success. - */ -int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val, bitmask; - - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; - val = snd_soc_read(codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); - if (e->shift_l != e->shift_r) - ucontrol->value.enumerated.item[1] = - (val >> e->shift_r) & (bitmask - 1); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); - -/** - * snd_soc_put_enum_double - enumerated double mixer put callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a double enumerated mixer. - * - * Returns 0 for success. - */ -int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val; - unsigned short mask, bitmask; - - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->mask - 1) - return -EINVAL; - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->mask - 1) - return -EINVAL; - val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; - } - - return snd_soc_update_bits(codec, e->reg, mask, val); -} -EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); - -/** - * snd_soc_info_enum_ext - external enumerated single mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about an external enumerated - * single mixer. - * - * Returns 0 for success. - */ -int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = e->mask; - - if (uinfo->value.enumerated.item > e->mask - 1) - uinfo->value.enumerated.item = e->mask - 1; - strcpy(uinfo->value.enumerated.name, - e->texts[uinfo->value.enumerated.item]); - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_enum_ext); - -/** - * snd_soc_info_volsw_ext - external single mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a single external mixer control. - * - * Returns 0 for success. - */ -int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int mask = kcontrol->private_value; - - uinfo->type = - mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); - -/** - * snd_soc_info_bool_ext - external single boolean mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a single boolean external mixer control. - * - * Returns 0 for success. - */ -int snd_soc_info_bool_ext(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; -} -EXPORT_SYMBOL_GPL(snd_soc_info_bool_ext); - -/** - * snd_soc_info_volsw - single mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_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; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - - uinfo->type = - mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = shift == rshift ? 1 : 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw); - -/** - * snd_soc_get_volsw - single mixer get callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to get the value of a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0x01; - - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, reg) >> shift) & mask; - if (shift != rshift) - ucontrol->value.integer.value[1] = - (snd_soc_read(codec, reg) >> rshift) & mask; - if (invert) { - ucontrol->value.integer.value[0] = - mask - ucontrol->value.integer.value[0]; - if (shift != rshift) - ucontrol->value.integer.value[1] = - mask - ucontrol->value.integer.value[1]; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw); - -/** - * snd_soc_put_volsw - single mixer put callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a single mixer control. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0x01; - int err; - unsigned short val, val2, val_mask; - - val = (ucontrol->value.integer.value[0] & mask); - if (invert) - val = mask - val; - val_mask = mask << shift; - val = val << shift; - if (shift != rshift) { - val2 = (ucontrol->value.integer.value[1] & mask); - if (invert) - val2 = mask - val2; - val_mask |= mask << rshift; - val |= val2 << rshift; - } - err = snd_soc_update_bits(codec, reg, val_mask, val); - return err; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw); - -/** - * snd_soc_info_volsw_2r - double mixer info callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to provide information about a double mixer control that - * spans 2 codec registers. - * - * Returns 0 for success. - */ -int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - int mask = (kcontrol->private_value >> 12) & 0xff; - - uinfo->type = - mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = mask; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); - -/** - * snd_soc_get_volsw_2r - double mixer get callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to get the value of a double mixer control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 24) & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int mask = (kcontrol->private_value >> 12) & 0xff; - int invert = (kcontrol->private_value >> 20) & 0x01; - - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, reg) >> shift) & mask; - ucontrol->value.integer.value[1] = - (snd_soc_read(codec, reg2) >> shift) & mask; - if (invert) { - ucontrol->value.integer.value[0] = - mask - ucontrol->value.integer.value[0]; - ucontrol->value.integer.value[1] = - mask - ucontrol->value.integer.value[1]; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r); - -/** - * snd_soc_put_volsw_2r - double mixer set callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a double mixer control that spans 2 registers. - * - * Returns 0 for success. - */ -int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int reg2 = (kcontrol->private_value >> 24) & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int mask = (kcontrol->private_value >> 12) & 0xff; - int invert = (kcontrol->private_value >> 20) & 0x01; - int err; - unsigned short val, val2, val_mask; - - val_mask = mask << shift; - val = (ucontrol->value.integer.value[0] & mask); - val2 = (ucontrol->value.integer.value[1] & mask); - - if (invert) { - val = mask - val; - val2 = mask - val2; - } - - val = val << shift; - val2 = val2 << shift; - - if ((err = snd_soc_update_bits(codec, reg, val_mask, val)) < 0) - return err; - - err = snd_soc_update_bits(codec, reg2, val_mask, val2); - return err; -} -EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); - -static int __devinit snd_soc_init(void) -{ - printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); - return platform_driver_register(&soc_driver); -} - -static void snd_soc_exit(void) -{ - platform_driver_unregister(&soc_driver); -} - -module_init(snd_soc_init); -module_exit(snd_soc_exit); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC Core"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c deleted file mode 100644 index 7caf8c7b0ac5..000000000000 --- a/trunk/sound/soc/soc-dapm.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* - * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management - * - * Copyright 2005 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. - * - * Revision history - * 12th Aug 2005 Initial version. - * 25th Oct 2005 Implemented path power domain. - * 18th Dec 2005 Implemented machine and stream level power domain. - * - * Features: - * o Changes power status of internal codec blocks depending on the - * dynamic configuration of codec internal audio paths and active - * DAC's/ADC's. - * o Platform power domain - can support external components i.e. amps and - * mic/meadphone insertion events. - * o Automatic Mic Bias support - * o Jack insertion power event initiation - e.g. hp insertion will enable - * sinks, dacs, etc - * o Delayed powerdown of audio susbsytem to reduce pops between a quick - * device reopen. - * - * Todo: - * o DAPM power change sequencing - allow for configurable per - * codec sequences. - * o Support for analogue bias optimisation. - * o Support for reduced codec oversampling rates. - * o Support for reduced codec bias currents. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug */ -#define DAPM_DEBUG 0 -#if DAPM_DEBUG -#define dump_dapm(codec, action) dbg_dump_dapm(codec, action) -#define dbg(format, arg...) printk(format, ## arg) -#else -#define dump_dapm(codec, action) -#define dbg(format, arg...) -#endif - -#define POP_DEBUG 0 -#if POP_DEBUG -#define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */ -#define pop_wait(time) schedule_timeout_interruptible(msecs_to_jiffies(time)) -#define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME) -#else -#define pop_dbg(format, arg...) -#define pop_wait(time) -#endif - -/* dapm power sequences - make this per codec in the future */ -static int dapm_up_seq[] = { - snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, - snd_soc_dapm_mux, snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_pga, - snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post -}; -static int dapm_down_seq[] = { - snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, - snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, - snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_post -}; - -static int dapm_status = 1; -module_param(dapm_status, int, 0); -MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); - -/* create a new dapm widget */ -static inline struct snd_soc_dapm_widget *dapm_cnew_widget( - const struct snd_soc_dapm_widget *_widget) -{ - return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); -} - -/* set up initial codec paths */ -static void dapm_set_path_status(struct snd_soc_dapm_widget *w, - struct snd_soc_dapm_path *p, int i) -{ - switch (w->id) { - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: { - int val; - int reg = w->kcontrols[i].private_value & 0xff; - int shift = (w->kcontrols[i].private_value >> 8) & 0x0f; - int mask = (w->kcontrols[i].private_value >> 16) & 0xff; - int invert = (w->kcontrols[i].private_value >> 24) & 0x01; - - val = snd_soc_read(w->codec, reg); - val = (val >> shift) & mask; - - if ((invert && !val) || (!invert && val)) - p->connect = 1; - else - p->connect = 0; - } - break; - case snd_soc_dapm_mux: { - struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; - int val, item, bitmask; - - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; - val = snd_soc_read(w->codec, e->reg); - item = (val >> e->shift_l) & (bitmask - 1); - - p->connect = 0; - for (i = 0; i < e->mask; i++) { - if (!(strcmp(p->name, e->texts[i])) && item == i) - p->connect = 1; - } - } - break; - /* does not effect routing - always connected */ - case snd_soc_dapm_pga: - case snd_soc_dapm_output: - case snd_soc_dapm_adc: - case snd_soc_dapm_input: - case snd_soc_dapm_dac: - case snd_soc_dapm_micbias: - case snd_soc_dapm_vmid: - p->connect = 1; - break; - /* does effect routing - dynamically connected */ - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_spk: - case snd_soc_dapm_line: - case snd_soc_dapm_pre: - case snd_soc_dapm_post: - p->connect = 0; - break; - } -} - -/* connect mux widget to it's interconnecting audio paths */ -static int dapm_connect_mux(struct snd_soc_codec *codec, - struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, - struct snd_soc_dapm_path *path, const char *control_name, - const struct snd_kcontrol_new *kcontrol) -{ - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - int i; - - for (i = 0; i < e->mask; i++) { - if (!(strcmp(control_name, e->texts[i]))) { - list_add(&path->list, &codec->dapm_paths); - list_add(&path->list_sink, &dest->sources); - list_add(&path->list_source, &src->sinks); - path->name = (char*)e->texts[i]; - dapm_set_path_status(dest, path, 0); - return 0; - } - } - - return -ENODEV; -} - -/* connect mixer widget to it's interconnecting audio paths */ -static int dapm_connect_mixer(struct snd_soc_codec *codec, - struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, - struct snd_soc_dapm_path *path, const char *control_name) -{ - int i; - - /* search for mixer kcontrol */ - for (i = 0; i < dest->num_kcontrols; i++) { - if (!strcmp(control_name, dest->kcontrols[i].name)) { - list_add(&path->list, &codec->dapm_paths); - list_add(&path->list_sink, &dest->sources); - list_add(&path->list_source, &src->sinks); - path->name = dest->kcontrols[i].name; - dapm_set_path_status(dest, path, i); - return 0; - } - } - return -ENODEV; -} - -/* update dapm codec register bits */ -static int dapm_update_bits(struct snd_soc_dapm_widget *widget) -{ - int change, power; - unsigned short old, new; - struct snd_soc_codec *codec = widget->codec; - - /* check for valid widgets */ - if (widget->reg < 0 || widget->id == snd_soc_dapm_input || - widget->id == snd_soc_dapm_output || - widget->id == snd_soc_dapm_hp || - widget->id == snd_soc_dapm_mic || - widget->id == snd_soc_dapm_line || - widget->id == snd_soc_dapm_spk) - return 0; - - power = widget->power; - if (widget->invert) - power = (power ? 0:1); - - old = snd_soc_read(codec, widget->reg); - new = (old & ~(0x1 << widget->shift)) | (power << widget->shift); - - change = old != new; - if (change) { - pop_dbg("pop test %s : %s in %d ms\n", widget->name, - widget->power ? "on" : "off", POP_TIME); - snd_soc_write(codec, widget->reg, new); - pop_wait(POP_TIME); - } - dbg("reg old %x new %x change %d\n", old, new, change); - return change; -} - -/* ramps the volume up or down to minimise pops before or after a - * DAPM power event */ -static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power) -{ - const struct snd_kcontrol_new *k = widget->kcontrols; - - if (widget->muted && !power) - return 0; - if (!widget->muted && power) - return 0; - - if (widget->num_kcontrols && k) { - int reg = k->private_value & 0xff; - int shift = (k->private_value >> 8) & 0x0f; - int mask = (k->private_value >> 16) & 0xff; - int invert = (k->private_value >> 24) & 0x01; - - if (power) { - int i; - /* power up has happended, increase volume to last level */ - if (invert) { - for (i = mask; i > widget->saved_value; i--) - snd_soc_update_bits(widget->codec, reg, mask, i); - } else { - for (i = 0; i < widget->saved_value; i++) - snd_soc_update_bits(widget->codec, reg, mask, i); - } - widget->muted = 0; - } else { - /* power down is about to occur, decrease volume to mute */ - int val = snd_soc_read(widget->codec, reg); - int i = widget->saved_value = (val >> shift) & mask; - if (invert) { - for (; i < mask; i++) - snd_soc_update_bits(widget->codec, reg, mask, i); - } else { - for (; i > 0; i--) - snd_soc_update_bits(widget->codec, reg, mask, i); - } - widget->muted = 1; - } - } - return 0; -} - -/* create new dapm mixer control */ -static int dapm_new_mixer(struct snd_soc_codec *codec, - struct snd_soc_dapm_widget *w) -{ - int i, ret = 0; - char name[32]; - struct snd_soc_dapm_path *path; - - /* add kcontrol */ - for (i = 0; i < w->num_kcontrols; i++) { - - /* match name */ - list_for_each_entry(path, &w->sources, list_sink) { - - /* mixer/mux paths name must match control name */ - if (path->name != (char*)w->kcontrols[i].name) - continue; - - /* add dapm control with long name */ - snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name); - path->long_name = kstrdup (name, GFP_KERNEL); - if (path->long_name == NULL) - return -ENOMEM; - - path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, - path->long_name); - ret = snd_ctl_add(codec->card, path->kcontrol); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n", - path->long_name); - kfree(path->long_name); - path->long_name = NULL; - return ret; - } - } - } - return ret; -} - -/* create new dapm mux control */ -static int dapm_new_mux(struct snd_soc_codec *codec, - struct snd_soc_dapm_widget *w) -{ - struct snd_soc_dapm_path *path = NULL; - struct snd_kcontrol *kcontrol; - int ret = 0; - - if (!w->num_kcontrols) { - printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); - return -EINVAL; - } - - kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); - ret = snd_ctl_add(codec->card, kcontrol); - if (ret < 0) - goto err; - - list_for_each_entry(path, &w->sources, list_sink) - path->kcontrol = kcontrol; - - return ret; - -err: - printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); - return ret; -} - -/* create new dapm volume control */ -static int dapm_new_pga(struct snd_soc_codec *codec, - struct snd_soc_dapm_widget *w) -{ - struct snd_kcontrol *kcontrol; - int ret = 0; - - if (!w->num_kcontrols) - return -EINVAL; - - kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); - ret = snd_ctl_add(codec->card, kcontrol); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); - return ret; - } - - return ret; -} - -/* reset 'walked' bit for each dapm path */ -static inline void dapm_clear_walk(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_path *p; - - list_for_each_entry(p, &codec->dapm_paths, list) - p->walked = 0; -} - -/* - * Recursively check for a completed path to an active or physically connected - * output widget. Returns number of complete paths. - */ -static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) -{ - struct snd_soc_dapm_path *path; - int con = 0; - - if (widget->id == snd_soc_dapm_adc && widget->active) - return 1; - - if (widget->connected) { - /* connected pin ? */ - if (widget->id == snd_soc_dapm_output && !widget->ext) - return 1; - - /* connected jack or spk ? */ - if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || - widget->id == snd_soc_dapm_line) - return 1; - } - - list_for_each_entry(path, &widget->sinks, list_source) { - if (path->walked) - continue; - - if (path->sink && path->connect) { - path->walked = 1; - con += is_connected_output_ep(path->sink); - } - } - - return con; -} - -/* - * Recursively check for a completed path to an active or physically connected - * input widget. Returns number of complete paths. - */ -static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) -{ - struct snd_soc_dapm_path *path; - int con = 0; - - /* active stream ? */ - if (widget->id == snd_soc_dapm_dac && widget->active) - return 1; - - if (widget->connected) { - /* connected pin ? */ - if (widget->id == snd_soc_dapm_input && !widget->ext) - return 1; - - /* connected VMID/Bias for lower pops */ - if (widget->id == snd_soc_dapm_vmid) - return 1; - - /* connected jack ? */ - if (widget->id == snd_soc_dapm_mic || widget->id == snd_soc_dapm_line) - return 1; - } - - list_for_each_entry(path, &widget->sources, list_sink) { - if (path->walked) - continue; - - if (path->source && path->connect) { - path->walked = 1; - con += is_connected_input_ep(path->source); - } - } - - return con; -} - -/* - * Scan each dapm widget for complete audio path. - * A complete path is a route that has valid endpoints i.e.:- - * - * o DAC to output pin. - * o Input Pin to ADC. - * o Input pin to Output pin (bypass, sidetone) - * o DAC to ADC (loopback). - */ -static int dapm_power_widgets(struct snd_soc_codec *codec, int event) -{ - struct snd_soc_dapm_widget *w; - int in, out, i, c = 1, *seq = NULL, ret = 0, power_change, power; - - /* do we have a sequenced stream event */ - if (event == SND_SOC_DAPM_STREAM_START) { - c = ARRAY_SIZE(dapm_up_seq); - seq = dapm_up_seq; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - c = ARRAY_SIZE(dapm_down_seq); - seq = dapm_down_seq; - } - - for(i = 0; i < c; i++) { - list_for_each_entry(w, &codec->dapm_widgets, list) { - - /* is widget in stream order */ - if (seq && seq[i] && w->id != seq[i]) - continue; - - /* vmid - no action */ - if (w->id == snd_soc_dapm_vmid) - continue; - - /* active ADC */ - if (w->id == snd_soc_dapm_adc && w->active) { - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - w->power = (in != 0) ? 1 : 0; - dapm_update_bits(w); - continue; - } - - /* active DAC */ - if (w->id == snd_soc_dapm_dac && w->active) { - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - w->power = (out != 0) ? 1 : 0; - dapm_update_bits(w); - continue; - } - - /* programmable gain/attenuation */ - if (w->id == snd_soc_dapm_pga) { - int on; - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - w->power = on = (out != 0 && in != 0) ? 1 : 0; - - if (!on) - dapm_set_pga(w, on); /* lower volume to reduce pops */ - dapm_update_bits(w); - if (on) - dapm_set_pga(w, on); /* restore volume from zero */ - - continue; - } - - /* pre and post event widgets */ - if (w->id == snd_soc_dapm_pre) { - if (!w->event) - continue; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - continue; - } - if (w->id == snd_soc_dapm_post) { - if (!w->event) - continue; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - continue; - } - - /* all other widgets */ - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - power = (out != 0 && in != 0) ? 1 : 0; - power_change = (w->power == power) ? 0: 1; - w->power = power; - - /* call any power change event handlers */ - if (power_change) { - if (w->event) { - dbg("power %s event for %s flags %x\n", - w->power ? "on" : "off", w->name, w->event_flags); - if (power) { - /* power up event */ - if (w->event_flags & SND_SOC_DAPM_PRE_PMU) { - ret = w->event(w, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } - dapm_update_bits(w); - if (w->event_flags & SND_SOC_DAPM_POST_PMU){ - ret = w->event(w, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } - } else { - /* power down event */ - if (w->event_flags & SND_SOC_DAPM_PRE_PMD) { - ret = w->event(w, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - dapm_update_bits(w); - if (w->event_flags & SND_SOC_DAPM_POST_PMD) { - ret = w->event(w, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - } - } else - /* no event handler */ - dapm_update_bits(w); - } - } - } - - return ret; -} - -#if DAPM_DEBUG -static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) -{ - struct snd_soc_dapm_widget *w; - struct snd_soc_dapm_path *p = NULL; - int in, out; - - printk("DAPM %s %s\n", codec->name, action); - - list_for_each_entry(w, &codec->dapm_widgets, list) { - - /* only display widgets that effect routing */ - switch (w->id) { - case snd_soc_dapm_pre: - case snd_soc_dapm_post: - case snd_soc_dapm_vmid: - continue; - case snd_soc_dapm_mux: - case snd_soc_dapm_output: - case snd_soc_dapm_input: - case snd_soc_dapm_switch: - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_spk: - case snd_soc_dapm_line: - case snd_soc_dapm_micbias: - case snd_soc_dapm_dac: - case snd_soc_dapm_adc: - case snd_soc_dapm_pga: - case snd_soc_dapm_mixer: - if (w->name) { - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - printk("%s: %s in %d out %d\n", w->name, - w->power ? "On":"Off",in, out); - - list_for_each_entry(p, &w->sources, list_sink) { - if (p->connect) - printk(" in %s %s\n", p->name ? p->name : "static", - p->source->name); - } - list_for_each_entry(p, &w->sinks, list_source) { - if (p->connect) - printk(" out %s %s\n", p->name ? p->name : "static", - p->sink->name); - } - } - break; - } - } -} -#endif - -/* test and update the power status of a mux widget */ -static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, - struct snd_kcontrol *kcontrol, int mask, - int val, struct soc_enum* e) -{ - struct snd_soc_dapm_path *path; - int found = 0; - - if (widget->id != snd_soc_dapm_mux) - return -ENODEV; - - if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) - return 0; - - /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { - if (path->kcontrol != kcontrol) - continue; - - if (!path->name || ! e->texts[val]) - continue; - - found = 1; - /* we now need to match the string in the enum to the path */ - if (!(strcmp(path->name, e->texts[val]))) - path->connect = 1; /* new connection */ - else - path->connect = 0; /* old connection must be powered down */ - } - - if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); - - return 0; -} - -/* test and update the power status of a mixer widget */ -static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, - struct snd_kcontrol *kcontrol, int reg, - int val_mask, int val, int invert) -{ - struct snd_soc_dapm_path *path; - int found = 0; - - if (widget->id != snd_soc_dapm_mixer) - return -ENODEV; - - if (!snd_soc_test_bits(widget->codec, reg, val_mask, val)) - return 0; - - /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { - if (path->kcontrol != kcontrol) - continue; - - /* found, now check type */ - found = 1; - if (val) - /* new connection */ - path->connect = invert ? 0:1; - else - /* old connection must be powered down */ - path->connect = invert ? 1:0; - break; - } - - if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); - - return 0; -} - -/* show dapm widget status in sys fs */ -static ssize_t dapm_widget_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct snd_soc_device *devdata = dev_get_drvdata(dev); - struct snd_soc_codec *codec = devdata->codec; - struct snd_soc_dapm_widget *w; - int count = 0; - char *state = "not set"; - - list_for_each_entry(w, &codec->dapm_widgets, list) { - - /* only display widgets that burnm power */ - switch (w->id) { - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_spk: - case snd_soc_dapm_line: - case snd_soc_dapm_micbias: - case snd_soc_dapm_dac: - case snd_soc_dapm_adc: - case snd_soc_dapm_pga: - case snd_soc_dapm_mixer: - if (w->name) - count += sprintf(buf + count, "%s: %s\n", - w->name, w->power ? "On":"Off"); - break; - default: - break; - } - } - - switch(codec->dapm_state){ - case SNDRV_CTL_POWER_D0: - state = "D0"; - break; - case SNDRV_CTL_POWER_D1: - state = "D1"; - break; - case SNDRV_CTL_POWER_D2: - state = "D2"; - break; - case SNDRV_CTL_POWER_D3hot: - state = "D3hot"; - break; - case SNDRV_CTL_POWER_D3cold: - state = "D3cold"; - break; - } - count += sprintf(buf + count, "PM State: %s\n", state); - - return count; -} - -static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); - -int snd_soc_dapm_sys_add(struct device *dev) -{ - int ret = 0; - - if (dapm_status) - ret = device_create_file(dev, &dev_attr_dapm_widget); - - return ret; -} - -static void snd_soc_dapm_sys_remove(struct device *dev) -{ - if (dapm_status) - device_remove_file(dev, &dev_attr_dapm_widget); -} - -/* free all dapm widgets and resources */ -static void dapm_free_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_widget *w, *next_w; - struct snd_soc_dapm_path *p, *next_p; - - list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { - list_del(&w->list); - kfree(w); - } - - list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { - list_del(&p->list); - kfree(p->long_name); - kfree(p); - } -} - -/** - * snd_soc_dapm_sync_endpoints - scan and power dapm paths - * @codec: audio codec - * - * Walks all dapm audio paths and powers widgets according to their - * stream or path usage. - * - * Returns 0 for success. - */ -int snd_soc_dapm_sync_endpoints(struct snd_soc_codec *codec) -{ - return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_sync_endpoints); - -/** - * snd_soc_dapm_connect_input - connect dapm widgets - * @codec: audio codec - * @sink: name of target widget - * @control: mixer control name - * @source: name of source name - * - * Connects 2 dapm widgets together via a named audio path. The sink is - * the widget receiving the audio signal, whilst the source is the sender - * of the audio signal. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, - const char * control, const char *source) -{ - struct snd_soc_dapm_path *path; - struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; - int ret = 0; - - /* find src and dest widgets */ - list_for_each_entry(w, &codec->dapm_widgets, list) { - - if (!wsink && !(strcmp(w->name, sink))) { - wsink = w; - continue; - } - if (!wsource && !(strcmp(w->name, source))) { - wsource = w; - } - } - - if (wsource == NULL || wsink == NULL) - return -ENODEV; - - path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); - if (!path) - return -ENOMEM; - - path->source = wsource; - path->sink = wsink; - INIT_LIST_HEAD(&path->list); - INIT_LIST_HEAD(&path->list_source); - INIT_LIST_HEAD(&path->list_sink); - - /* check for external widgets */ - 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->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) - wsource->ext = 1; - } - - /* connect static paths */ - if (control == NULL) { - list_add(&path->list, &codec->dapm_paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); - path->connect = 1; - return 0; - } - - /* connect dynamic paths */ - switch(wsink->id) { - case snd_soc_dapm_adc: - case snd_soc_dapm_dac: - case snd_soc_dapm_pga: - case snd_soc_dapm_input: - case snd_soc_dapm_output: - case snd_soc_dapm_micbias: - case snd_soc_dapm_vmid: - case snd_soc_dapm_pre: - case snd_soc_dapm_post: - list_add(&path->list, &codec->dapm_paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); - path->connect = 1; - return 0; - case snd_soc_dapm_mux: - ret = dapm_connect_mux(codec, wsource, wsink, path, control, - &wsink->kcontrols[0]); - if (ret != 0) - goto err; - break; - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - ret = dapm_connect_mixer(codec, wsource, wsink, path, control); - if (ret != 0) - goto err; - break; - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_line: - case snd_soc_dapm_spk: - list_add(&path->list, &codec->dapm_paths); - list_add(&path->list_sink, &wsink->sources); - list_add(&path->list_source, &wsource->sinks); - path->connect = 0; - return 0; - } - return 0; - -err: - printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, - control, sink); - kfree(path); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input); - -/** - * snd_soc_dapm_new_widgets - add new dapm widgets - * @codec: audio codec - * - * Checks the codec for any new dapm widgets and creates them if found. - * - * Returns 0 for success. - */ -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_widget *w; - - mutex_lock(&codec->mutex); - list_for_each_entry(w, &codec->dapm_widgets, list) - { - if (w->new) - continue; - - switch(w->id) { - case snd_soc_dapm_switch: - case snd_soc_dapm_mixer: - dapm_new_mixer(codec, w); - break; - case snd_soc_dapm_mux: - dapm_new_mux(codec, w); - break; - case snd_soc_dapm_adc: - case snd_soc_dapm_dac: - case snd_soc_dapm_pga: - dapm_new_pga(codec, w); - break; - case snd_soc_dapm_input: - case snd_soc_dapm_output: - case snd_soc_dapm_micbias: - case snd_soc_dapm_spk: - case snd_soc_dapm_hp: - case snd_soc_dapm_mic: - case snd_soc_dapm_line: - case snd_soc_dapm_vmid: - case snd_soc_dapm_pre: - case snd_soc_dapm_post: - break; - } - w->new = 1; - } - - dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); - mutex_unlock(&codec->mutex); - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); - -/** - * snd_soc_dapm_get_volsw - dapm mixer get callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to get the value of a dapm mixer control. - * - * Returns 0 for success. - */ -int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0x01; - - /* return the saved value if we are powered down */ - if (widget->id == snd_soc_dapm_pga && !widget->power) { - ucontrol->value.integer.value[0] = widget->saved_value; - return 0; - } - - ucontrol->value.integer.value[0] = - (snd_soc_read(widget->codec, reg) >> shift) & mask; - if (shift != rshift) - ucontrol->value.integer.value[1] = - (snd_soc_read(widget->codec, reg) >> rshift) & mask; - if (invert) { - ucontrol->value.integer.value[0] = - mask - ucontrol->value.integer.value[0]; - if (shift != rshift) - ucontrol->value.integer.value[1] = - mask - ucontrol->value.integer.value[1]; - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw); - -/** - * snd_soc_dapm_put_volsw - dapm mixer set callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a dapm mixer control. - * - * Returns 0 for success. - */ -int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0x0f; - int rshift = (kcontrol->private_value >> 12) & 0x0f; - int mask = (kcontrol->private_value >> 16) & 0xff; - int invert = (kcontrol->private_value >> 24) & 0x01; - unsigned short val, val2, val_mask; - int ret; - - val = (ucontrol->value.integer.value[0] & mask); - - if (invert) - val = mask - val; - val_mask = mask << shift; - val = val << shift; - if (shift != rshift) { - val2 = (ucontrol->value.integer.value[1] & mask); - if (invert) - val2 = mask - val2; - val_mask |= mask << rshift; - val |= val2 << rshift; - } - - mutex_lock(&widget->codec->mutex); - widget->value = val; - - /* save volume value if the widget is powered down */ - if (widget->id == snd_soc_dapm_pga && !widget->power) { - widget->saved_value = val; - mutex_unlock(&widget->codec->mutex); - return 1; - } - - dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert); - if (widget->event) { - if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { - ret = widget->event(widget, SND_SOC_DAPM_PRE_REG); - if (ret < 0) - goto out; - } - ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); - if (widget->event_flags & SND_SOC_DAPM_POST_REG) - ret = widget->event(widget, SND_SOC_DAPM_POST_REG); - } else - ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); - -out: - mutex_unlock(&widget->codec->mutex); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); - -/** - * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to get the value of a dapm enumerated double mixer control. - * - * Returns 0 for success. - */ -int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val, bitmask; - - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; - val = snd_soc_read(widget->codec, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); - if (e->shift_l != e->shift_r) - ucontrol->value.enumerated.item[1] = - (val >> e->shift_r) & (bitmask - 1); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); - -/** - * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback - * @kcontrol: mixer control - * @uinfo: control element information - * - * Callback to set the value of a dapm enumerated double mixer control. - * - * Returns 0 for success. - */ -int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val, mux; - unsigned short mask, bitmask; - int ret = 0; - - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->mask - 1) - return -EINVAL; - mux = ucontrol->value.enumerated.item[0]; - val = mux << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->mask - 1) - return -EINVAL; - val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; - } - - mutex_lock(&widget->codec->mutex); - widget->value = val; - dapm_mux_update_power(widget, kcontrol, mask, mux, e); - if (widget->event) { - if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { - ret = widget->event(widget, SND_SOC_DAPM_PRE_REG); - if (ret < 0) - goto out; - } - ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); - if (widget->event_flags & SND_SOC_DAPM_POST_REG) - ret = widget->event(widget, SND_SOC_DAPM_POST_REG); - } else - ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); - -out: - mutex_unlock(&widget->codec->mutex); - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); - -/** - * snd_soc_dapm_new_control - create new dapm control - * @codec: audio codec - * @widget: widget template - * - * Creates a new dapm control based upon the template. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, - const struct snd_soc_dapm_widget *widget) -{ - struct snd_soc_dapm_widget *w; - - if ((w = dapm_cnew_widget(widget)) == NULL) - return -ENOMEM; - - w->codec = codec; - INIT_LIST_HEAD(&w->sources); - INIT_LIST_HEAD(&w->sinks); - INIT_LIST_HEAD(&w->list); - list_add(&w->list, &codec->dapm_widgets); - - /* machine layer set ups unconnected pins and insertions */ - w->connected = 1; - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); - -/** - * snd_soc_dapm_stream_event - send a stream event to the dapm core - * @codec: audio codec - * @stream: stream name - * @event: stream event - * - * Sends a stream event to the dapm core. The core then makes any - * necessary widget power changes. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, - char *stream, int event) -{ - struct snd_soc_dapm_widget *w; - - if (stream == NULL) - return 0; - - mutex_lock(&codec->mutex); - list_for_each_entry(w, &codec->dapm_widgets, list) - { - if (!w->sname) - continue; - dbg("widget %s\n %s stream %s event %d\n", w->name, w->sname, - stream, event); - if (strstr(w->sname, stream)) { - switch(event) { - case SND_SOC_DAPM_STREAM_START: - w->active = 1; - break; - case SND_SOC_DAPM_STREAM_STOP: - w->active = 0; - break; - case SND_SOC_DAPM_STREAM_SUSPEND: - if (w->active) - w->suspend = 1; - w->active = 0; - break; - case SND_SOC_DAPM_STREAM_RESUME: - if (w->suspend) { - w->active = 1; - w->suspend = 0; - } - break; - case SND_SOC_DAPM_STREAM_PAUSE_PUSH: - break; - case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: - break; - } - } - } - mutex_unlock(&codec->mutex); - - dapm_power_widgets(codec, event); - dump_dapm(codec, __FUNCTION__); - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); - -/** - * snd_soc_dapm_set_endpoint - set audio endpoint status - * @codec: audio codec - * @endpoint: audio signal endpoint (or start point) - * @status: point status - * - * Set audio endpoint status - connected or disconnected. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_set_endpoint(struct snd_soc_codec *codec, - char *endpoint, int status) -{ - struct snd_soc_dapm_widget *w; - - list_for_each_entry(w, &codec->dapm_widgets, list) { - if (!strcmp(w->name, endpoint)) { - w->connected = status; - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_set_endpoint); - -/** - * snd_soc_dapm_free - free dapm resources - * @socdev: SoC device - * - * Free all dapm widgets and resources. - */ -void snd_soc_dapm_free(struct snd_soc_device *socdev) -{ - struct snd_soc_codec *codec = socdev->codec; - - snd_soc_dapm_sys_remove(socdev->dev); - dapm_free_widgets(codec); -} -EXPORT_SYMBOL_GPL(snd_soc_dapm_free); - -/* Module information */ -MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/sparc/dbri.c b/trunk/sound/sparc/dbri.c index 25a2a7333006..4ceb09d215d8 100644 --- a/trunk/sound/sparc/dbri.c +++ b/trunk/sound/sparc/dbri.c @@ -678,7 +678,7 @@ static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len) * The JUMP cmd points to the new cmd string. * It also releases the cmdlock spinlock. * - * Lock must be held before calling this. + * Lock must not be held before calling this. */ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) { diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 4dfb91d4398a..19bdcc74c96c 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -186,7 +186,6 @@ struct snd_usb_substream { u64 formats; /* format bitmasks (all or'ed) */ unsigned int num_formats; /* number of supported audio formats (list) */ struct list_head fmt_list; /* format list */ - struct snd_pcm_hw_constraint_list rate_list; /* limited rates */ spinlock_t lock; struct snd_urb_ops ops; /* callbacks (must be filled at init) */ @@ -254,7 +253,7 @@ static int prepare_capture_sync_urb(struct snd_usb_substream *subs, struct urb *urb) { unsigned char *cp = urb->transfer_buffer; - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; urb->dev = ctx->subs->dev; /* we need to set this at each time */ urb->iso_frame_desc[0].length = 3; @@ -276,7 +275,7 @@ static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs, struct urb *urb) { unsigned char *cp = urb->transfer_buffer; - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; urb->dev = ctx->subs->dev; /* we need to set this at each time */ urb->iso_frame_desc[0].length = 4; @@ -314,7 +313,7 @@ static int prepare_capture_urb(struct snd_usb_substream *subs, struct urb *urb) { int i, offs; - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; offs = 0; urb->dev = ctx->subs->dev; /* we need to set this at each time */ @@ -392,16 +391,6 @@ static int retire_capture_urb(struct snd_usb_substream *subs, return 0; } -/* - * Process after capture complete when paused. Nothing to do. - */ -static int retire_paused_capture_urb(struct snd_usb_substream *subs, - struct snd_pcm_runtime *runtime, - struct urb *urb) -{ - return 0; -} - /* * prepare urb for full speed playback sync pipe @@ -413,7 +402,7 @@ static int prepare_playback_sync_urb(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *urb) { - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; urb->dev = ctx->subs->dev; /* we need to set this at each time */ urb->iso_frame_desc[0].length = 3; @@ -431,7 +420,7 @@ static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *urb) { - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; urb->dev = ctx->subs->dev; /* we need to set this at each time */ urb->iso_frame_desc[0].length = 4; @@ -504,13 +493,13 @@ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) } /* - * Prepare urb for streaming before playback starts or when paused. + * Prepare urb for streaming before playback starts. * - * We don't have any data, so we send a frame of silence. + * We don't yet have data, so we send a frame of silence. */ -static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, - struct snd_pcm_runtime *runtime, - struct urb *urb) +static int prepare_startup_playback_urb(struct snd_usb_substream *subs, + struct snd_pcm_runtime *runtime, + struct urb *urb) { unsigned int i, offs, counts; struct snd_urb_ctx *ctx = urb->context; @@ -548,7 +537,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, unsigned int counts; unsigned long flags; int period_elapsed = 0; - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; stride = runtime->frame_bits >> 3; @@ -633,7 +622,7 @@ static int retire_playback_urb(struct snd_usb_substream *subs, */ static struct snd_urb_ops audio_urb_ops[2] = { { - .prepare = prepare_nodata_playback_urb, + .prepare = prepare_startup_playback_urb, .retire = retire_playback_urb, .prepare_sync = prepare_playback_sync_urb, .retire_sync = retire_playback_sync_urb, @@ -648,7 +637,7 @@ static struct snd_urb_ops audio_urb_ops[2] = { static struct snd_urb_ops audio_urb_ops_high_speed[2] = { { - .prepare = prepare_nodata_playback_urb, + .prepare = prepare_startup_playback_urb, .retire = retire_playback_urb, .prepare_sync = prepare_playback_sync_urb_hs, .retire_sync = retire_playback_sync_urb_hs, @@ -666,7 +655,7 @@ static struct snd_urb_ops audio_urb_ops_high_speed[2] = { */ static void snd_complete_urb(struct urb *urb) { - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; struct snd_usb_substream *subs = ctx->subs; struct snd_pcm_substream *substream = ctx->subs->pcm_substream; int err = 0; @@ -689,7 +678,7 @@ static void snd_complete_urb(struct urb *urb) */ static void snd_complete_sync_urb(struct urb *urb) { - struct snd_urb_ctx *ctx = urb->context; + struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context; struct snd_usb_substream *subs = ctx->subs; struct snd_pcm_substream *substream = ctx->subs->pcm_substream; int err = 0; @@ -936,14 +925,10 @@ static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: subs->ops.prepare = prepare_playback_urb; return 0; case SNDRV_PCM_TRIGGER_STOP: return deactivate_urbs(subs, 0, 0); - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - subs->ops.prepare = prepare_nodata_playback_urb; - return 0; default: return -EINVAL; } @@ -959,16 +944,9 @@ static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - subs->ops.retire = retire_capture_urb; return start_urbs(subs, substream->runtime); case SNDRV_PCM_TRIGGER_STOP: return deactivate_urbs(subs, 0, 0); - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - subs->ops.retire = retire_paused_capture_urb; - return 0; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - subs->ops.retire = retire_capture_urb; - return 0; default: return -EINVAL; } @@ -1430,7 +1408,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) static int snd_usb_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { - struct snd_usb_substream *subs = substream->runtime->private_data; + struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data; struct audioformat *fmt; unsigned int channels, rate, format; int ret, changed; @@ -1486,7 +1464,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, */ static int snd_usb_hw_free(struct snd_pcm_substream *substream) { - struct snd_usb_substream *subs = substream->runtime->private_data; + struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data; subs->cur_audiofmt = NULL; subs->cur_rate = 0; @@ -1527,20 +1505,33 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) /* for playback, submit the URBs now; otherwise, the first hwptr_done * updates for all URBs would happen at the same time when starting */ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { - subs->ops.prepare = prepare_nodata_playback_urb; + subs->ops.prepare = prepare_startup_playback_urb; return start_urbs(subs, runtime); } else return 0; } -static struct snd_pcm_hardware snd_usb_hardware = +static struct snd_pcm_hardware snd_usb_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE, + SNDRV_PCM_INFO_BLOCK_TRANSFER, + .buffer_bytes_max = 1024 * 1024, + .period_bytes_min = 64, + .period_bytes_max = 512 * 1024, + .periods_min = 2, + .periods_max = 1024, +}; + +static struct snd_pcm_hardware snd_usb_capture = +{ + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER, .buffer_bytes_max = 1024 * 1024, .period_bytes_min = 64, .period_bytes_max = 512 * 1024, @@ -1819,33 +1810,28 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs) { - struct audioformat *fp; - int count = 0, needs_knot = 0; + struct list_head *p; + struct snd_pcm_hw_constraint_list constraints_rates; int err; - list_for_each_entry(fp, &subs->fmt_list, list) { - if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) - return 0; - count += fp->nr_rates; - if (fp->needs_knot) - needs_knot = 1; - } - if (!needs_knot) - return 0; + list_for_each(p, &subs->fmt_list) { + struct audioformat *fp; + fp = list_entry(p, struct audioformat, list); - subs->rate_list.count = count; - subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); - subs->rate_list.mask = 0; - count = 0; - list_for_each_entry(fp, &subs->fmt_list, list) { - int i; - for (i = 0; i < fp->nr_rates; i++) - subs->rate_list.list[count++] = fp->rate_table[i]; - } - err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - &subs->rate_list); - if (err < 0) - return err; + if (!fp->needs_knot) + continue; + + constraints_rates.count = fp->nr_rates; + constraints_rates.list = fp->rate_table; + constraints_rates.mask = 0; + + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + + if (err < 0) + return err; + } return 0; } @@ -1918,7 +1904,8 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return 0; } -static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) +static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction, + struct snd_pcm_hardware *hw) { struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; @@ -1926,7 +1913,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) subs->interface = -1; subs->format = 0; - runtime->hw = snd_usb_hardware; + runtime->hw = *hw; runtime->private_data = subs; subs->pcm_substream = substream; return setup_hw_info(runtime, subs); @@ -1947,7 +1934,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) static int snd_usb_playback_open(struct snd_pcm_substream *substream) { - return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); + return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK, &snd_usb_playback); } static int snd_usb_playback_close(struct snd_pcm_substream *substream) @@ -1957,7 +1944,7 @@ static int snd_usb_playback_close(struct snd_pcm_substream *substream) static int snd_usb_capture_open(struct snd_pcm_substream *substream) { - return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE); + return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE, &snd_usb_capture); } static int snd_usb_capture_close(struct snd_pcm_substream *substream) @@ -2244,7 +2231,6 @@ static void free_substream(struct snd_usb_substream *subs) kfree(fp->rate_table); kfree(fp); } - kfree(subs->rate_list.list); } @@ -2470,7 +2456,6 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform * build the rate table and bitmap flags */ int r, idx, c; - unsigned int nonzero_rates = 0; /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ static unsigned int conv_rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, @@ -2493,7 +2478,6 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; fp->rate_table[r] = rate; - nonzero_rates |= rate; if (rate < fp->rate_min) fp->rate_min = rate; else if (rate > fp->rate_max) @@ -2509,10 +2493,6 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform if (!found) fp->needs_knot = 1; } - if (!nonzero_rates) { - hwc_debug("All rates were zero. Skipping format!\n"); - return -1; - } if (fp->needs_knot) fp->rates |= SNDRV_PCM_RATE_KNOT; } else { @@ -3077,58 +3057,6 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip, return 0; } -/* - * Create a stream for an Edirol UA-101 interface. - * Copy, paste and modify from Edirol UA-1000 - */ -static int create_ua101_quirk(struct snd_usb_audio *chip, - struct usb_interface *iface, - const struct snd_usb_audio_quirk *quirk) -{ - static const struct audioformat ua101_format = { - .format = SNDRV_PCM_FORMAT_S32_LE, - .fmt_type = USB_FORMAT_TYPE_I, - .altsetting = 1, - .altset_idx = 1, - .attributes = 0, - .rates = SNDRV_PCM_RATE_CONTINUOUS, - }; - struct usb_host_interface *alts; - struct usb_interface_descriptor *altsd; - struct audioformat *fp; - int stream, err; - - if (iface->num_altsetting != 2) - return -ENXIO; - alts = &iface->altsetting[1]; - altsd = get_iface_desc(alts); - if (alts->extralen != 18 || alts->extra[1] != USB_DT_CS_INTERFACE || - altsd->bNumEndpoints != 1) - return -ENXIO; - - fp = kmemdup(&ua101_format, sizeof(*fp), GFP_KERNEL); - if (!fp) - return -ENOMEM; - - fp->channels = alts->extra[11]; - fp->iface = altsd->bInterfaceNumber; - fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; - fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; - fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); - fp->rate_max = fp->rate_min = combine_triple(&alts->extra[15]); - - stream = (fp->endpoint & USB_DIR_IN) - ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; - err = add_audio_endpoint(chip, stream, fp); - if (err < 0) { - kfree(fp); - return err; - } - /* FIXME: playback must be synchronized to capture */ - usb_set_interface(chip->dev, fp->iface, 0); - return 0; -} - static int snd_usb_create_quirk(struct snd_usb_audio *chip, struct usb_interface *iface, const struct snd_usb_audio_quirk *quirk); @@ -3310,7 +3238,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, - [QUIRK_AUDIO_EDIROL_UA101] = create_ua101_quirk, }; if (quirk->type < QUIRK_TYPE_COUNT) { diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index 2272f45a1867..0f4b2b8541d6 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -159,7 +159,6 @@ enum quirk_type { QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_EDIROL_UA700_UA25, QUIRK_AUDIO_EDIROL_UA1000, - QUIRK_AUDIO_EDIROL_UA101, QUIRK_TYPE_COUNT }; diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index 25b4ab4f61e7..a7e9563a01df 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -1098,37 +1098,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -/* Roland UA-101 in High-Speed Mode only */ -{ - USB_DEVICE(0x0582, 0x007d), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "UA-101", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_EDIROL_UA101 - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_EDIROL_UA101 - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } - } - } -}, + /* TODO: add Edirol UA-101 support */ { /* has ID 0x0081 when not in "Advanced Driver" mode */ USB_DEVICE(0x0582, 0x0080),