diff --git a/[refs] b/[refs] index 2845ef994c0f..42ca3be0a310 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5c34202b8bf942da411b6599668a76b07449bbfd +refs/heads/master: c5b7bede71853d92fc747cdc12fa5234b6045731 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index c6322c760348..498ff31f3aa1 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -328,3 +328,22 @@ Who: Adrian Bunk --------------------------- +What: libata.spindown_compat module parameter +When: Dec 2008 +Why: halt(8) synchronizes caches for and spins down libata disks + because libata didn't use to spin down disk on system halt + (only synchronized caches). + Spin down on system halt is now implemented and can be tested + using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop. + Because issuing spin down command to an already spun down disk + makes some disks spin up just to spin down again, the old + behavior needs to be maintained till userspace tool is updated + to check the sysfs node and not to spin down disks with the + node set to one. + This module parameter is to give userspace tool the time to + get updated and should be removed after userspace is + reasonably updated. +Who: Tejun Heo + +--------------------------- + diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 73e9a174b642..57b878cc393c 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 macpro MacPro support + w2jc ASUS W2JC auto auto-config reading BIOS (default) ALC883/888 @@ -852,6 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig 3-jack with SPDIF OUT 6stack-dig 6-jack with SPDIF OUT 3stack-660 3-jack (for ALC660VD) + lenovo Lenovo 3000 C200 auto auto-config reading BIOS (default) CMI9880 @@ -909,6 +911,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. macbook Intel Mac Book macbook-pro-v1 Intel Mac Book Pro 1st generation macbook-pro Intel Mac Book Pro 2nd generation + imac-intel Intel iMac STAC9202/9250/9251 ref Reference board, base config @@ -924,6 +927,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. vaio Setup for VAIO FE550G/SZ110 vaio-ar Setup for VAIO AR + The model name "genric" is treated as a special case. When this + model is given, the driver uses the generic codec parser without + "codec-patch". It's sometimes good for testing and debugging. + If the default configuration doesn't work and one of the above matches with your device, report it together with the PCI subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel @@ -1278,6 +1285,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. port - port number or -1 (disable) irq - IRQ number or -1 (disable) pnp - PnP detection - 0 = disable, 1 = enable (default) + uart_enter - Issue UART_ENTER command at open - bool, default = on This module supports multiple devices and PnP. @@ -1692,6 +1700,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple devices, autoprobe and hotplugging. + Module snd-usb-caiaq + -------------------- + + Module for caiaq UB audio interfaces, + * Native Instruments RigKontrol2 + * Native Instruments Kore Controller + * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 8 DJ + + This module supports multiple devices, autoprobe and hotplugging. + Module snd-usb-usx2y -------------------- @@ -2046,4 +2065,4 @@ Links and Addresses https://bugtrack.alsa-project.org/bugs/ ALSA Developers ML - mailto:alsa-devel@lists.sourceforge.net + mailto:alsa-devel@alsa-project.org diff --git a/trunk/Documentation/sound/alsa/Bt87x.txt b/trunk/Documentation/sound/alsa/Bt87x.txt index 11edb2fd2a5a..f158cde8b065 100644 --- a/trunk/Documentation/sound/alsa/Bt87x.txt +++ b/trunk/Documentation/sound/alsa/Bt87x.txt @@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with other values than the default 32000 (often it's 44100 or 64000). If you have an unknown card, please mail the ID and board name to -, regardless of whether audio capture works or -not, so that future versions of this driver know about your card. +, regardless of whether audio capture works +or not, so that future versions of this driver know about your card. Audio modes diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index d7bb2e2e4d9b..712e8c8333cc 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -52,7 +52,7 @@ 51 -> ProVideo PV952 [1540:9524] 52 -> AverMedia AverTV/305 [1461:2108] 53 -> ASUS TV-FM 7135 [1043:4845] - 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304] + 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,5168:5214,1489:0214,5168:0304] 55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306] 56 -> Avermedia AVerTV 307 [1461:a70a] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] @@ -111,3 +111,6 @@ 110 -> Avermedia M102 [1461:f31e] 111 -> ASUS P7131 4871 [1043:4871] 112 -> ASUSTeK P7131 Hybrid [1043:4876] +113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6] +114 -> KWorld DVB-T 210 [17de:7250] +115 -> Sabrent PCMCIA TV-PCB05 [0919:2003] diff --git a/trunk/Documentation/video4linux/sn9c102.txt b/trunk/Documentation/video4linux/sn9c102.txt index 5fe0ad7dfc20..279717c96f63 100644 --- a/trunk/Documentation/video4linux/sn9c102.txt +++ b/trunk/Documentation/video4linux/sn9c102.txt @@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers: Vendor ID Product ID --------- ---------- +0x0458 0x7025 +0x045e 0x00f5 +0x045e 0x00f7 0x0471 0x0327 0x0471 0x0328 0x0c45 0x6001 @@ -432,7 +435,7 @@ Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120 HV7131D Hynix Semiconductor | Yes No No No HV7131R Hynix Semiconductor | No Yes Yes Yes MI-0343 Micron Technology | Yes No No No -MI-0360 Micron Technology | No Yes No No +MI-0360 Micron Technology | No Yes Yes Yes OV7630 OmniVision Technologies | Yes Yes No No OV7660 OmniVision Technologies | No No Yes Yes PAS106B PixArt Imaging | Yes No No No @@ -478,13 +481,12 @@ scaling factor is restored to 1. This driver supports two different video formats: the first one is the "8-bit Sequential Bayer" format and can be used to obtain uncompressed video data from the device through the current I/O method, while the second one provides -"raw" compressed video data (without frame headers not related to the -compressed data). The compression quality may vary from 0 to 1 and can be -selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 -ioctl's. For maximum flexibility, both the default active video format and the -default compression quality depend on how the image sensor being used is -initialized (as described in the documentation of the API for the image sensors -supplied by this driver). +either "raw" compressed video data (without frame headers not related to the +compressed data) or standard JPEG (with frame headers). The compression quality +may vary from 0 to 1 and can be selected or queried thanks to the +VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility, +both the default active video format and the default compression quality +depend on how the image sensor being used is initialized. 11. Video frame formats [1] diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index bd558ac5bb73..975f263f5c21 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER P: Johannes Berg M: johannes@sipsolutions.net L: linuxppc-dev@ozlabs.org -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Maintained APM DRIVER @@ -3239,13 +3239,13 @@ S: Maintained SOUND P: Jaroslav Kysela M: perex@suse.cz -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Maintained SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT P: Liam Girdwood M: liam.girdwood@wolfsonmicro.com -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Supported SPI SUBSYSTEM diff --git a/trunk/arch/i386/kernel/verify_cpu.S b/trunk/arch/i386/kernel/verify_cpu.S index e51a8695d54e..b2a9d80b6421 100644 --- a/trunk/arch/i386/kernel/verify_cpu.S +++ b/trunk/arch/i386/kernel/verify_cpu.S @@ -10,7 +10,9 @@ verify_cpu: #if CONFIG_X86_MINIMUM_CPU_MODEL >= 4 pushfl - orl $(1<<18),(%esp) # try setting AC + pop %eax + orl $(1<<18),%eax # try setting AC + push %eax popfl pushfl popl %eax diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 6e41471449c0..de1bff659969 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -31,6 +31,10 @@ config ZONE_DMA def_bool y depends on !IA64_SGI_SN2 +config QUICKLIST + bool + default y + config MMU bool default y diff --git a/trunk/arch/ia64/hp/common/hwsw_iommu.c b/trunk/arch/ia64/hp/common/hwsw_iommu.c index 2153bcacbe6c..94e57109fad6 100644 --- a/trunk/arch/ia64/hp/common/hwsw_iommu.c +++ b/trunk/arch/ia64/hp/common/hwsw_iommu.c @@ -63,7 +63,7 @@ use_swiotlb (struct device *dev) return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask); } -void +void __init hwsw_init (void) { /* default to a smallish 2MB sw I/O TLB */ diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index b50bf208678e..144b056282af 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1583,5 +1583,7 @@ sys_call_table: data8 sys_vmsplice data8 sys_ni_syscall // reserved for move_pages data8 sys_getcpu + data8 sys_epoll_pwait // 1305 + data8 sys_utimensat .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/trunk/arch/ia64/kernel/err_inject.c b/trunk/arch/ia64/kernel/err_inject.c index 6a49600cf337..b642648cc2ac 100644 --- a/trunk/arch/ia64/kernel/err_inject.c +++ b/trunk/arch/ia64/kernel/err_inject.c @@ -291,5 +291,5 @@ module_init(err_inject_init); module_exit(err_inject_exit); MODULE_AUTHOR("Fenghua Yu "); -MODULE_DESCRIPTION("MC error injection kenrel sysfs interface"); +MODULE_DESCRIPTION("MC error injection kernel sysfs interface"); MODULE_LICENSE("GPL"); diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index ce49c85c928f..b4c239685d2e 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -104,6 +104,17 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) irq_redir[irq] = (char) (redir & 0xff); } } + +bool is_affinity_mask_valid(cpumask_t cpumask) +{ + if (ia64_platform_is("sn2")) { + /* Only allow one CPU to be specified in the smp_affinity mask */ + if (cpus_weight(cpumask) != 1) + return false; + } + return true; +} + #endif /* CONFIG_SMP */ #ifdef CONFIG_HOTPLUG_CPU diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 4f5fd0960ba7..72e593e94053 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -370,14 +370,18 @@ static int __kprobes valid_kprobe_addr(int template, int slot, static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) { - kcb->prev_kprobe.kp = kprobe_running(); - kcb->prev_kprobe.status = kcb->kprobe_status; + unsigned int i; + i = atomic_add_return(1, &kcb->prev_kprobe_index); + kcb->prev_kprobe[i-1].kp = kprobe_running(); + kcb->prev_kprobe[i-1].status = kcb->kprobe_status; } static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) { - __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; - kcb->kprobe_status = kcb->prev_kprobe.status; + unsigned int i; + i = atomic_sub_return(1, &kcb->prev_kprobe_index); + __get_cpu_var(current_kprobe) = kcb->prev_kprobe[i].kp; + kcb->kprobe_status = kcb->prev_kprobe[i].status; } static void __kprobes set_current_kprobe(struct kprobe *p, diff --git a/trunk/arch/ia64/kernel/machvec.c b/trunk/arch/ia64/kernel/machvec.c index 9620822270a6..13df337508e7 100644 --- a/trunk/arch/ia64/kernel/machvec.c +++ b/trunk/arch/ia64/kernel/machvec.c @@ -35,7 +35,7 @@ lookup_machvec (const char *name) return 0; } -void +void __init machvec_init (const char *name) { struct ia64_machine_vector *mv; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index f8ae709de0b5..26814de6c29a 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -118,7 +118,9 @@ static ia64_mc_info_t ia64_mc_info; #define CPE_HISTORY_LENGTH 5 #define CMC_HISTORY_LENGTH 5 +#ifdef CONFIG_ACPI static struct timer_list cpe_poll_timer; +#endif static struct timer_list cmc_poll_timer; /* * This variable tells whether we are currently in polling mode. diff --git a/trunk/arch/ia64/mm/contig.c b/trunk/arch/ia64/mm/contig.c index 44ce5ed9444c..7ac8592a35b6 100644 --- a/trunk/arch/ia64/mm/contig.c +++ b/trunk/arch/ia64/mm/contig.c @@ -88,7 +88,7 @@ void show_mem(void) printk(KERN_INFO "%d pages shared\n", total_shared); printk(KERN_INFO "%d pages swap cached\n", total_cached); printk(KERN_INFO "Total of %ld pages in page table cache\n", - pgtable_quicklist_total_size()); + quicklist_total_size()); printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages()); } diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 94844442812a..38085ac18338 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -561,7 +561,7 @@ void show_mem(void) printk(KERN_INFO "%d pages shared\n", total_shared); printk(KERN_INFO "%d pages swap cached\n", total_cached); printk(KERN_INFO "Total of %ld pages in page table cache\n", - pgtable_quicklist_total_size()); + quicklist_total_size()); printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages()); } diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index cffb1e8325e8..c14abefabafa 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -39,9 +39,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -DEFINE_PER_CPU(unsigned long *, __pgtable_quicklist); -DEFINE_PER_CPU(long, __pgtable_quicklist_size); - extern void ia64_tlb_init (void); unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL; @@ -56,54 +53,6 @@ EXPORT_SYMBOL(vmem_map); struct page *zero_page_memmap_ptr; /* map entry for zero page */ EXPORT_SYMBOL(zero_page_memmap_ptr); -#define MIN_PGT_PAGES 25UL -#define MAX_PGT_FREES_PER_PASS 16L -#define PGT_FRACTION_OF_NODE_MEM 16 - -static inline long -max_pgt_pages(void) -{ - u64 node_free_pages, max_pgt_pages; - -#ifndef CONFIG_NUMA - node_free_pages = nr_free_pages(); -#else - node_free_pages = node_page_state(numa_node_id(), NR_FREE_PAGES); -#endif - max_pgt_pages = node_free_pages / PGT_FRACTION_OF_NODE_MEM; - max_pgt_pages = max(max_pgt_pages, MIN_PGT_PAGES); - return max_pgt_pages; -} - -static inline long -min_pages_to_free(void) -{ - long pages_to_free; - - pages_to_free = pgtable_quicklist_size - max_pgt_pages(); - pages_to_free = min(pages_to_free, MAX_PGT_FREES_PER_PASS); - return pages_to_free; -} - -void -check_pgt_cache(void) -{ - long pages_to_free; - - if (unlikely(pgtable_quicklist_size <= MIN_PGT_PAGES)) - return; - - preempt_disable(); - while (unlikely((pages_to_free = min_pages_to_free()) > 0)) { - while (pages_to_free--) { - free_page((unsigned long)pgtable_quicklist_alloc()); - } - preempt_enable(); - preempt_disable(); - } - preempt_enable(); -} - void lazy_mmu_prot_update (pte_t pte) { diff --git a/trunk/arch/ia64/sn/kernel/io_common.c b/trunk/arch/ia64/sn/kernel/io_common.c index d48bcd83253c..7ed72d3faf73 100644 --- a/trunk/arch/ia64/sn/kernel/io_common.c +++ b/trunk/arch/ia64/sn/kernel/io_common.c @@ -364,7 +364,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev) element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); if (!element) { - dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); + dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__); return; } element->sysdata = SN_PCIDEV_INFO(dev); diff --git a/trunk/arch/ia64/sn/kernel/xpc_partition.c b/trunk/arch/ia64/sn/kernel/xpc_partition.c index 57c723f5cba4..7ba403232cb8 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_partition.c +++ b/trunk/arch/ia64/sn/kernel/xpc_partition.c @@ -574,7 +574,7 @@ xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version, u64 remote_vars_pa, struct xpc_vars *remote_vars) { part->remote_rp_version = remote_rp_version; - dev_dbg(xpc_part, " remote_rp_version = 0x%016lx\n", + dev_dbg(xpc_part, " remote_rp_version = 0x%016x\n", part->remote_rp_version); part->remote_rp_stamp = *remote_rp_stamp; diff --git a/trunk/arch/ia64/sn/kernel/xpnet.c b/trunk/arch/ia64/sn/kernel/xpnet.c index 88fad85ceeff..da7213530972 100644 --- a/trunk/arch/ia64/sn/kernel/xpnet.c +++ b/trunk/arch/ia64/sn/kernel/xpnet.c @@ -343,8 +343,8 @@ xpnet_dev_open(struct net_device *dev) enum xpc_retval ret; - dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, " - "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity, + dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, " + "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity, XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS); diff --git a/trunk/arch/x86_64/kernel/aperture.c b/trunk/arch/x86_64/kernel/aperture.c index a52af5820592..a3d450d6c15b 100644 --- a/trunk/arch/x86_64/kernel/aperture.c +++ b/trunk/arch/x86_64/kernel/aperture.c @@ -86,7 +86,7 @@ static int __init aperture_valid(u64 aper_base, u32 aper_size) printk("Aperture too small (%d MB)\n", aper_size>>20); return 0; } - if (aper_base + aper_size >= 0xffffffff) { + if (aper_base + aper_size > 0x100000000UL) { printk("Aperture beyond 4GB. Ignoring.\n"); return 0; } diff --git a/trunk/arch/x86_64/kernel/bugs.c b/trunk/arch/x86_64/kernel/bugs.c index 12b585b5345d..c141e7a7ff55 100644 --- a/trunk/arch/x86_64/kernel/bugs.c +++ b/trunk/arch/x86_64/kernel/bugs.c @@ -13,6 +13,7 @@ void __init check_bugs(void) { identify_cpu(&boot_cpu_data); + mtrr_bp_init(); #if !defined(CONFIG_SMP) printk("CPU: "); print_cpu_info(&boot_cpu_data); diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 373ef66ca1dc..ae091cdc1a4d 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -476,7 +476,7 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size) aper_base <<= 25; aper_size = (32 * 1024 * 1024) << aper_order; - if (aper_base + aper_size >= 0xffffffff || !aper_size) + if (aper_base + aper_size > 0x100000000UL || !aper_size) aper_base = 0; *size = aper_size; diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index db51577bda32..eb6524f3ac29 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -891,9 +891,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #ifdef CONFIG_X86_MCE mcheck_init(c); #endif - if (c == &boot_cpu_data) - mtrr_bp_init(); - else + if (c != &boot_cpu_data) mtrr_ap_init(); #ifdef CONFIG_NUMA numa_add_cpu(smp_processor_id()); diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index f031b8732330..ad1f59c1b3fc 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -2,11 +2,9 @@ # SATA/PATA driver configuration # -menu "Serial ATA (prod) and Parallel ATA (experimental) drivers" +menuconfig ATA + tristate "Serial ATA (prod) and Parallel ATA (experimental) drivers" depends on HAS_IOMEM - -config ATA - tristate "ATA device support" depends on BLOCK depends on !(M32R || M68K) || BROKEN depends on !SUN4 || BROKEN @@ -24,6 +22,19 @@ config ATA_NONSTANDARD bool default n +config ATA_ACPI + bool + depends on ACPI && PCI + default y + help + This option adds support for ATA-related ACPI objects. + These ACPI objects add the ability to retrieve taskfiles + from the ACPI BIOS and write them to the disk controller. + These objects may be related to performance, security, + power management, or other areas. + You can disable this at kernel boot time by using the + option libata.noacpi=1 + config SATA_AHCI tristate "AHCI SATA support" depends on PCI @@ -157,19 +168,6 @@ config SATA_INIC162X help This option enables support for Initio 162x Serial ATA. -config SATA_ACPI - bool - depends on ACPI && PCI - default y - help - This option adds support for SATA-related ACPI objects. - These ACPI objects add the ability to retrieve taskfiles - from the ACPI BIOS and write them to the disk controller. - These objects may be related to performance, security, - power management, or other areas. - You can disable this at kernel boot time by using the - option libata.noacpi=1 - config PATA_ALI tristate "ALi PATA support (Experimental)" depends on PCI && EXPERIMENTAL @@ -585,6 +583,4 @@ config PATA_SCC If unsure, say N. -endif -endmenu - +endif # ATA diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index 6f42a0e2812d..8149c68ac2c7 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -69,4 +69,4 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o -libata-$(CONFIG_SATA_ACPI) += libata-acpi.o +libata-$(CONFIG_ATA_ACPI) += libata-acpi.o diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index d9617892fc23..1ae443d7ab92 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -250,10 +250,6 @@ static struct scsi_host_template ahci_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations ahci_ops = { @@ -400,6 +396,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 92a491ddd030..c3d753296bc6 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -54,7 +54,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_ready(dev)) { + if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; @@ -90,10 +90,6 @@ static struct scsi_host_template generic_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations generic_port_ops = { @@ -145,7 +141,7 @@ static int all_generic_ide; /* Set to claim all devices */ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) { u16 command; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &generic_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -153,7 +149,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id .udma_mask = 0x3f, .port_ops = &generic_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; /* Don't use the generic entry unless instructed to do so */ if (id->driver_data == 1 && all_generic_ide == 0) @@ -179,7 +175,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id if (dev->vendor == PCI_VENDOR_ID_AL) ata_pci_clear_simplex(dev); - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static struct pci_device_id ata_generic[] = { diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 4a795fdb6a02..13b6b1df2ac4 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -275,10 +275,6 @@ static struct scsi_host_template piix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations piix_pata_ops = { @@ -1034,7 +1030,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int printed_version; struct device *dev = &pdev->dev; struct ata_port_info port_info[2]; - struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] }; + const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] }; struct piix_host_priv *hpriv; unsigned long port_flags; @@ -1093,7 +1089,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) port_info[1].mwdma_mask = 0; port_info[1].udma_mask = 0; } - return ata_pci_init_one(pdev, ppinfo, 2); + return ata_pci_init_one(pdev, ppi); } static int __init piix_init(void) diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index cb3eab6e379d..ed4138e24b0c 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -270,8 +270,7 @@ static int get_sata_adr(struct device *dev, acpi_handle handle, /** * do_drive_get_GTF - get the drive bootup default taskfile settings - * @ap: the ata_port for the drive - * @ix: target ata_device (drive) index + * @dev: target ATA device * @gtf_length: number of bytes of _GTF data returned at @gtf_address * @gtf_address: buffer containing _GTF taskfile arrays * @@ -286,20 +285,19 @@ static int get_sata_adr(struct device *dev, acpi_handle handle, * The returned @gtf_length and @gtf_address are only valid if the * function return value is 0. */ -static int do_drive_get_GTF(struct ata_port *ap, int ix, - unsigned int *gtf_length, unsigned long *gtf_address, - unsigned long *obj_loc) +static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, + unsigned long *gtf_address, unsigned long *obj_loc) { - acpi_status status; - acpi_handle dev_handle = NULL; - acpi_handle chan_handle, drive_handle; - acpi_integer pcidevfn = 0; - u32 dev_adr; - struct acpi_buffer output; - union acpi_object *out_obj; - struct device *dev = ap->host->dev; - struct ata_device *atadev = &ap->device[ix]; - int err = -ENODEV; + struct ata_port *ap = dev->ap; + acpi_status status; + acpi_handle dev_handle = NULL; + acpi_handle chan_handle, drive_handle; + acpi_integer pcidevfn = 0; + u32 dev_adr; + struct acpi_buffer output; + union acpi_object *out_obj; + struct device *gdev = ap->host->dev; + int err = -ENODEV; *gtf_length = 0; *gtf_address = 0UL; @@ -309,14 +307,14 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, return 0; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n", + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", __FUNCTION__, ap->port_no); - if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) { + if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: " + ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: " "ata_dev_present: %d, PORT_DISABLED: %lu\n", - __FUNCTION__, ata_dev_enabled(atadev), + __FUNCTION__, ata_dev_enabled(dev), ap->flags & ATA_FLAG_DISABLED); goto out; } @@ -324,19 +322,19 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, /* Don't continue if device has no _ADR method. * _GTF is intended for known motherboard devices. */ if (!(ap->cbl == ATA_CBL_SATA)) { - err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn); + err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn); if (err < 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: pata_get_dev_handle failed (%d)\n", __FUNCTION__, err); goto out; } } else { - err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn); + err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn); if (err < 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: sata_get_dev_handle failed (%d\n", __FUNCTION__, err); goto out; @@ -344,7 +342,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, } /* Get this drive's _ADR info. if not already known. */ - if (!atadev->obj_handle) { + if (!dev->obj_handle) { if (!(ap->cbl == ATA_CBL_SATA)) { /* get child objects of dev_handle == channel objects, * + _their_ children == drive objects */ @@ -352,7 +350,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, chan_handle = acpi_get_child(dev_handle, ap->port_no); if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: chan adr=%d: chan_handle=0x%p\n", __FUNCTION__, ap->port_no, chan_handle); @@ -361,26 +359,26 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, goto out; } /* TBD: could also check ACPI object VALID bits */ - drive_handle = acpi_get_child(chan_handle, ix); + drive_handle = acpi_get_child(chan_handle, dev->devno); if (!drive_handle) { err = -ENODEV; goto out; } - dev_adr = ix; - atadev->obj_handle = drive_handle; + dev_adr = dev->devno; + dev->obj_handle = drive_handle; } else { /* for SATA mode */ dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(dev, dev_handle, pcidevfn, 0, - ap, atadev, &dev_adr); + err = get_sata_adr(gdev, dev_handle, pcidevfn, 0, + ap, dev, &dev_adr); } if (err < 0 || dev_adr == SATA_ADR_RSVD || - !atadev->obj_handle) { + !dev->obj_handle) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: get_sata/pata_adr failed: " "err=%d, dev_adr=%u, obj_handle=0x%p\n", __FUNCTION__, err, dev_adr, - atadev->obj_handle); + dev->obj_handle); goto out; } } @@ -391,11 +389,11 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, /* _GTF has no input parameters */ err = -EIO; - status = acpi_evaluate_object(atadev->obj_handle, "_GTF", + status = acpi_evaluate_object(dev->obj_handle, "_GTF", NULL, &output); if (ACPI_FAILURE(status)) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF error: status = 0x%x\n", __FUNCTION__, status); goto out; @@ -403,7 +401,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, if (!output.length || !output.pointer) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: " + ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " "length or ptr is NULL (0x%llx, 0x%p)\n", __FUNCTION__, (unsigned long long)output.length, @@ -416,7 +414,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, if (out_obj->type != ACPI_TYPE_BUFFER) { kfree(output.pointer); if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: " + ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " "error: expected object type of " " ACPI_TYPE_BUFFER, got 0x%x\n", __FUNCTION__, out_obj->type); @@ -427,7 +425,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, if (!out_obj->buffer.length || !out_obj->buffer.pointer || out_obj->buffer.length % REGS_PER_GTF) { if (ata_msg_drv(ap)) - ata_dev_printk(atadev, KERN_ERR, + ata_dev_printk(dev, KERN_ERR, "%s: unexpected GTF length (%d) or addr (0x%p)\n", __FUNCTION__, out_obj->buffer.length, out_obj->buffer.pointer); @@ -439,7 +437,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, *gtf_address = (unsigned long)out_obj->buffer.pointer; *obj_loc = (unsigned long)out_obj; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: returning " + ata_dev_printk(dev, KERN_DEBUG, "%s: returning " "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n", __FUNCTION__, *gtf_length, *gtf_address, *obj_loc); err = 0; @@ -449,7 +447,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, /** * taskfile_load_raw - send taskfile registers to host controller - * @ap: Port to which output is sent + * @dev: target ATA device * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) * * Outputs ATA taskfile to standard ATA host controller using MMIO @@ -466,15 +464,15 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix, * LOCKING: TBD: * Inherited from caller. */ -static void taskfile_load_raw(struct ata_port *ap, - struct ata_device *atadev, - const struct taskfile_array *gtf) +static void taskfile_load_raw(struct ata_device *dev, + const struct taskfile_array *gtf) { + struct ata_port *ap = dev->ap; struct ata_taskfile tf; unsigned int err; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " + ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: " "%02x %02x %02x %02x %02x %02x %02x\n", __FUNCTION__, gtf->tfa[0], gtf->tfa[1], gtf->tfa[2], @@ -485,7 +483,7 @@ static void taskfile_load_raw(struct ata_port *ap, && (gtf->tfa[6] == 0)) return; - ata_tf_init(atadev, &tf); + ata_tf_init(dev, &tf); /* convert gtf to tf */ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ @@ -498,17 +496,16 @@ static void taskfile_load_raw(struct ata_port *ap, tf.device = gtf->tfa[5]; /* 0x1f6 */ tf.command = gtf->tfa[6]; /* 0x1f7 */ - err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0); + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); if (err && ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_ERR, + ata_dev_printk(dev, KERN_ERR, "%s: ata_exec_internal failed: %u\n", __FUNCTION__, err); } /** * do_drive_set_taskfiles - write the drive taskfile settings from _GTF - * @ap: the ata_port for the drive - * @atadev: target ata_device + * @dev: target ATA device * @gtf_length: total number of bytes of _GTF taskfiles * @gtf_address: location of _GTF taskfile arrays * @@ -517,30 +514,31 @@ static void taskfile_load_raw(struct ata_port *ap, * Write {gtf_address, length gtf_length} in groups of * REGS_PER_GTF bytes. */ -static int do_drive_set_taskfiles(struct ata_port *ap, - struct ata_device *atadev, unsigned int gtf_length, - unsigned long gtf_address) +static int do_drive_set_taskfiles(struct ata_device *dev, + unsigned int gtf_length, + unsigned long gtf_address) { - int err = -ENODEV; - int gtf_count = gtf_length / REGS_PER_GTF; - int ix; + struct ata_port *ap = dev->ap; + int err = -ENODEV; + int gtf_count = gtf_length / REGS_PER_GTF; + int ix; struct taskfile_array *gtf; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n", + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", __FUNCTION__, ap->port_no); if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA)) return 0; - if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) + if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) goto out; if (!gtf_count) /* shouldn't be here */ goto out; if (gtf_length % REGS_PER_GTF) { if (ata_msg_drv(ap)) - ata_dev_printk(atadev, KERN_ERR, + ata_dev_printk(dev, KERN_ERR, "%s: unexpected GTF length (%d)\n", __FUNCTION__, gtf_length); goto out; @@ -551,7 +549,7 @@ static int do_drive_set_taskfiles(struct ata_port *ap, (gtf_address + ix * REGS_PER_GTF); /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */ - taskfile_load_raw(ap, atadev, gtf); + taskfile_load_raw(dev, gtf); } err = 0; @@ -567,11 +565,11 @@ static int do_drive_set_taskfiles(struct ata_port *ap, */ int ata_acpi_exec_tfs(struct ata_port *ap) { - int ix; - int ret =0; - unsigned int gtf_length; - unsigned long gtf_address; - unsigned long obj_loc; + int ix; + int ret = 0; + unsigned int gtf_length; + unsigned long gtf_address; + unsigned long obj_loc; if (libata_noacpi) return 0; @@ -584,11 +582,13 @@ int ata_acpi_exec_tfs(struct ata_port *ap) return 0; for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { - if (!ata_dev_enabled(&ap->device[ix])) + struct ata_device *dev = &ap->device[ix]; + + if (!ata_dev_enabled(dev)) continue; - ret = do_drive_get_GTF(ap, ix, - >f_length, >f_address, &obj_loc); + ret = do_drive_get_GTF(dev, >f_length, >f_address, + &obj_loc); if (ret < 0) { if (ata_msg_probe(ap)) ata_port_printk(ap, KERN_DEBUG, @@ -597,8 +597,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) break; } - ret = do_drive_set_taskfiles(ap, &ap->device[ix], - gtf_length, gtf_address); + ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address); kfree((void *)obj_loc); if (ret < 0) { if (ata_msg_probe(ap)) @@ -614,8 +613,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) /** * ata_acpi_push_id - send Identify data to drive - * @ap: the ata_port for the drive - * @ix: drive index + * @dev: target ATA device * * _SDD ACPI object: for SATA mode only * Must be after Identify (Packet) Device -- uses its data @@ -623,57 +621,57 @@ int ata_acpi_exec_tfs(struct ata_port *ap) * method and if it fails for whatever reason, we should still * just keep going. */ -int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) +int ata_acpi_push_id(struct ata_device *dev) { - acpi_handle handle; - acpi_integer pcidevfn; - int err; - struct device *dev = ap->host->dev; - struct ata_device *atadev = &ap->device[ix]; - u32 dev_adr; - acpi_status status; - struct acpi_object_list input; - union acpi_object in_params[1]; + struct ata_port *ap = dev->ap; + acpi_handle handle; + acpi_integer pcidevfn; + int err; + struct device *gdev = ap->host->dev; + u32 dev_adr; + acpi_status status; + struct acpi_object_list input; + union acpi_object in_params[1]; if (libata_noacpi) return 0; if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", - __FUNCTION__, ix, ap->port_no); + ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", + __FUNCTION__, dev->devno, ap->port_no); /* Don't continue if not a SATA device. */ if (!(ap->cbl == ATA_CBL_SATA)) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: Not a SATA device\n", __FUNCTION__); goto out; } /* Don't continue if device has no _ADR method. * _SDD is intended for known motherboard devices. */ - err = sata_get_dev_handle(dev, &handle, &pcidevfn); + err = sata_get_dev_handle(gdev, &handle, &pcidevfn); if (err < 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: sata_get_dev_handle failed (%d\n", __FUNCTION__, err); goto out; } /* Get this drive's _ADR info, if not already known */ - if (!atadev->obj_handle) { + if (!dev->obj_handle) { dev_adr = SATA_ADR_RSVD; - err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev, + err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev, &dev_adr); if (err < 0 || dev_adr == SATA_ADR_RSVD || - !atadev->obj_handle) { + !dev->obj_handle) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s: get_sata_adr failed: " "err=%d, dev_adr=%u, obj_handle=0x%p\n", __FUNCTION__, err, dev_adr, - atadev->obj_handle); + dev->obj_handle); goto out; } } @@ -683,19 +681,19 @@ int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) input.count = 1; input.pointer = in_params; in_params[0].type = ACPI_TYPE_BUFFER; - in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS; - in_params[0].buffer.pointer = (u8 *)atadev->id; + in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS; + in_params[0].buffer.pointer = (u8 *)dev->id; /* Output buffer: _SDD has no output */ /* It's OK for _SDD to be missing too. */ - swap_buf_le16(atadev->id, ATA_ID_WORDS); - status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL); - swap_buf_le16(atadev->id, ATA_ID_WORDS); + swap_buf_le16(dev->id, ATA_ID_WORDS); + status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL); + swap_buf_le16(dev->id, ATA_ID_WORDS); err = ACPI_FAILURE(status) ? -EIO : 0; if (err < 0) { if (ata_msg_probe(ap)) - ata_dev_printk(atadev, KERN_DEBUG, + ata_dev_printk(dev, KERN_DEBUG, "%s _SDD error: status = 0x%x\n", __FUNCTION__, status); } diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 4595d1f8cf60..4166407eb47c 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -101,6 +101,12 @@ int libata_noacpi = 1; module_param_named(noacpi, libata_noacpi, int, 0444); MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set"); +int ata_spindown_compat = 1; +module_param_named(spindown_compat, ata_spindown_compat, int, 0644); +MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown " + "behavior. Will be removed. More info can be found in " + "Documentation/feature-removal-schedule.txt\n"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -1654,7 +1660,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, struct ata_taskfile tf; unsigned int err_mask = 0; const char *reason; - int tried_spinup = 0; + int may_fallback = 1, tried_spinup = 0; int rc; if (ata_msg_ctl(ap)) @@ -1698,11 +1704,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, return -ENOENT; } + /* Device or controller might have reported the wrong + * device class. Give a shot at the other IDENTIFY if + * the current one is aborted by the device. + */ + if (may_fallback && + (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { + may_fallback = 0; + + if (class == ATA_DEV_ATA) + class = ATA_DEV_ATAPI; + else + class = ATA_DEV_ATA; + goto retry; + } + rc = -EIO; reason = "I/O error"; goto err_out; } + /* Falling back doesn't make sense if ID data was read + * successfully at least once. + */ + may_fallback = 0; + swap_buf_le16(id, ATA_ID_WORDS); /* sanity check */ @@ -1843,7 +1869,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); /* set _SDD */ - rc = ata_acpi_push_id(ap, dev->devno); + rc = ata_acpi_push_id(dev); if (rc) { ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n", rc); @@ -2860,7 +2886,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) dev = &ap->device[i]; /* don't update suspended devices' xfer mode */ - if (!ata_dev_ready(dev)) + if (!ata_dev_enabled(dev)) continue; rc = ata_dev_set_mode(dev); @@ -5845,37 +5871,11 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, */ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) { - int i, j, rc; + int rc; rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); - if (rc) - goto fail; - - /* EH is quiescent now. Fail if we have any ready device. - * This happens if hotplug occurs between completion of device - * suspension and here. - */ - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - for (j = 0; j < ATA_MAX_DEVICES; j++) { - struct ata_device *dev = &ap->device[j]; - - if (ata_dev_ready(dev)) { - ata_port_printk(ap, KERN_WARNING, - "suspend failed, device %d " - "still active\n", dev->devno); - rc = -EBUSY; - goto fail; - } - } - } - - host->dev->power.power_state = mesg; - return 0; - - fail: - ata_host_resume(host); + if (rc == 0) + host->dev->power.power_state = mesg; return rc; } @@ -5984,6 +5984,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) if (!ap) return NULL; + ap->pflags |= ATA_PFLAG_INITIALIZING; ap->lock = &host->lock; ap->flags = ATA_FLAG_DISABLED; ap->print_id = -1; @@ -6352,6 +6353,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ehi->action |= ATA_EH_SOFTRESET; ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; + ap->pflags &= ~ATA_PFLAG_INITIALIZING; ap->pflags |= ATA_PFLAG_LOADING; ata_port_schedule_eh(ap); @@ -6876,6 +6878,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); EXPORT_SYMBOL_GPL(ata_pci_init_native_host); +EXPORT_SYMBOL_GPL(ata_pci_init_bmdma); EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); @@ -6889,11 +6892,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter); EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ -#ifdef CONFIG_PM -EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); -EXPORT_SYMBOL_GPL(ata_scsi_device_resume); -#endif /* CONFIG_PM */ - EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_port_schedule_eh); EXPORT_SYMBOL_GPL(ata_port_abort); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index 8256655ce7d9..5309c312f517 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -77,29 +77,12 @@ static void ata_eh_finish(struct ata_port *ap); #ifdef CONFIG_PM static void ata_eh_handle_port_suspend(struct ata_port *ap); static void ata_eh_handle_port_resume(struct ata_port *ap); -static int ata_eh_suspend(struct ata_port *ap, - struct ata_device **r_failed_dev); -static void ata_eh_prep_resume(struct ata_port *ap); -static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev); #else /* CONFIG_PM */ static void ata_eh_handle_port_suspend(struct ata_port *ap) { } static void ata_eh_handle_port_resume(struct ata_port *ap) { } - -static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) -{ - return 0; -} - -static void ata_eh_prep_resume(struct ata_port *ap) -{ } - -static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) -{ - return 0; -} #endif /* CONFIG_PM */ static void ata_ering_record(struct ata_ering *ering, int is_io, @@ -568,6 +551,9 @@ void ata_port_schedule_eh(struct ata_port *ap) { WARN_ON(!ap->ops->error_handler); + if (ap->pflags & ATA_PFLAG_INITIALIZING) + return; + ap->pflags |= ATA_PFLAG_EH_PENDING; scsi_schedule_eh(ap->scsi_host); @@ -1791,7 +1777,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, if (ehc->i.flags & ATA_EHI_DID_RESET) readid_flags |= ATA_READID_POSTRESET; - if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { + if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { if (ata_port_offline(ap)) { rc = -EIO; goto err; @@ -1872,166 +1858,6 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, return rc; } -#ifdef CONFIG_PM -/** - * ata_eh_suspend - handle suspend EH action - * @ap: target host port - * @r_failed_dev: result parameter to indicate failing device - * - * Handle suspend EH action. Disk devices are spinned down and - * other types of devices are just marked suspended. Once - * suspended, no EH action to the device is allowed until it is - * resumed. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise - */ -static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) -{ - struct ata_device *dev; - int i, rc = 0; - - DPRINTK("ENTER\n"); - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - unsigned long flags; - unsigned int action, err_mask; - - dev = &ap->device[i]; - action = ata_eh_dev_action(dev); - - if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND)) - continue; - - WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED); - - ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND); - - if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { - /* flush cache */ - rc = ata_flush_cache(dev); - if (rc) - break; - - /* spin down */ - err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to " - "spin down (err_mask=0x%x)\n", - err_mask); - rc = -EIO; - break; - } - } - - spin_lock_irqsave(ap->lock, flags); - dev->flags |= ATA_DFLAG_SUSPENDED; - spin_unlock_irqrestore(ap->lock, flags); - - ata_eh_done(ap, dev, ATA_EH_SUSPEND); - } - - if (rc) - *r_failed_dev = dev; - - DPRINTK("EXIT\n"); - return rc; -} - -/** - * ata_eh_prep_resume - prep for resume EH action - * @ap: target host port - * - * Clear SUSPENDED in preparation for scheduled resume actions. - * This allows other parts of EH to access the devices being - * resumed. - * - * LOCKING: - * Kernel thread context (may sleep). - */ -static void ata_eh_prep_resume(struct ata_port *ap) -{ - struct ata_device *dev; - unsigned long flags; - int i; - - DPRINTK("ENTER\n"); - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - unsigned int action; - - dev = &ap->device[i]; - action = ata_eh_dev_action(dev); - - if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) - continue; - - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_SUSPENDED; - spin_unlock_irqrestore(ap->lock, flags); - } - - DPRINTK("EXIT\n"); -} - -/** - * ata_eh_resume - handle resume EH action - * @ap: target host port - * @r_failed_dev: result parameter to indicate failing device - * - * Handle resume EH action. Target devices are already reset and - * revalidated. Spinning up is the only operation left. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise - */ -static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) -{ - struct ata_device *dev; - int i, rc = 0; - - DPRINTK("ENTER\n"); - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - unsigned int action, err_mask; - - dev = &ap->device[i]; - action = ata_eh_dev_action(dev); - - if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) - continue; - - ata_eh_about_to_do(ap, dev, ATA_EH_RESUME); - - if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { - err_mask = ata_do_simple_cmd(dev, - ATA_CMD_IDLEIMMEDIATE); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to " - "spin up (err_mask=0x%x)\n", - err_mask); - rc = -EIO; - break; - } - } - - ata_eh_done(ap, dev, ATA_EH_RESUME); - } - - if (rc) - *r_failed_dev = dev; - - DPRINTK("EXIT\n"); - return 0; -} -#endif /* CONFIG_PM */ - static int ata_port_nr_enabled(struct ata_port *ap) { int i, cnt = 0; @@ -2057,17 +1883,6 @@ static int ata_eh_skip_recovery(struct ata_port *ap) struct ata_eh_context *ehc = &ap->eh_context; int i; - /* skip if all possible devices are suspended */ - for (i = 0; i < ata_port_max_devices(ap); i++) { - struct ata_device *dev = &ap->device[i]; - - if (!(dev->flags & ATA_DFLAG_SUSPENDED)) - break; - } - - if (i == ata_port_max_devices(ap)) - return 1; - /* thaw frozen port, resume link and recover failed devices */ if ((ap->pflags & ATA_PFLAG_FROZEN) || (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) @@ -2147,9 +1962,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (ap->pflags & ATA_PFLAG_UNLOADING) goto out; - /* prep for resume */ - ata_eh_prep_resume(ap); - /* skip EH if possible. */ if (ata_eh_skip_recovery(ap)) ehc->i.action = 0; @@ -2177,11 +1989,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (rc) goto dev_fail; - /* resume devices */ - rc = ata_eh_resume(ap, &dev); - if (rc) - goto dev_fail; - /* configure transfer mode if necessary */ if (ehc->i.flags & ATA_EHI_SETMODE) { rc = ata_set_mode(ap, &dev); @@ -2190,25 +1997,16 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ehc->i.flags &= ~ATA_EHI_SETMODE; } - /* suspend devices */ - rc = ata_eh_suspend(ap, &dev); - if (rc) - goto dev_fail; - goto out; dev_fail: ehc->tries[dev->devno]--; switch (rc) { - case -EINVAL: - /* eeek, something went very wrong, give up */ - ehc->tries[dev->devno] = 0; - break; - case -ENODEV: /* device missing or wrong IDENTIFY data, schedule probing */ ehc->i.probe_mask |= (1 << dev->devno); + case -EINVAL: /* give it just one more chance */ ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); case -EIO: @@ -2390,22 +2188,13 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) * * Resume @ap. * - * This function also waits upto one second until all devices - * hanging off this port requests resume EH action. This is to - * prevent invoking EH and thus reset multiple times on resume. - * - * On DPM resume, where some of devices might not be resumed - * together, this may delay port resume upto one second, but such - * DPM resumes are rare and 1 sec delay isn't too bad. - * * LOCKING: * Kernel thread context (may sleep). */ static void ata_eh_handle_port_resume(struct ata_port *ap) { - unsigned long timeout; unsigned long flags; - int i, rc = 0; + int rc = 0; /* are we resuming? */ spin_lock_irqsave(ap->lock, flags); @@ -2416,31 +2205,12 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) } spin_unlock_irqrestore(ap->lock, flags); - /* spurious? */ - if (!(ap->pflags & ATA_PFLAG_SUSPENDED)) - goto done; + WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); if (ap->ops->port_resume) rc = ap->ops->port_resume(ap); - /* give devices time to request EH */ - timeout = jiffies + HZ; /* 1s max */ - while (1) { - for (i = 0; i < ATA_MAX_DEVICES; i++) { - struct ata_device *dev = &ap->device[i]; - unsigned int action = ata_eh_dev_action(dev); - - if ((dev->flags & ATA_DFLAG_SUSPENDED) && - !(action & ATA_EH_RESUME)) - break; - } - - if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout)) - break; - msleep(10); - } - - done: + /* report result */ spin_lock_irqsave(ap->lock, flags); ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); if (ap->pm_result) { diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 9afba2ba489e..dd81fa78cdcf 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf) } } -#ifdef CONFIG_PM -/** - * ata_scsi_device_suspend - suspend ATA device associated with sdev - * @sdev: the SCSI device to suspend - * @mesg: target power management message - * - * Request suspend EH action on the ATA device associated with - * @sdev and wait for the operation to complete. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) -{ - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = ata_scsi_find_dev(ap, sdev); - unsigned long flags; - unsigned int action; - int rc = 0; - - if (!dev) - goto out; - - spin_lock_irqsave(ap->lock, flags); - - /* wait for the previous resume to complete */ - while (dev->flags & ATA_DFLAG_SUSPENDED) { - spin_unlock_irqrestore(ap->lock, flags); - ata_port_wait_eh(ap); - spin_lock_irqsave(ap->lock, flags); - } - - /* if @sdev is already detached, nothing to do */ - if (sdev->sdev_state == SDEV_OFFLINE || - sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) - goto out_unlock; - - /* request suspend */ - action = ATA_EH_SUSPEND; - if (mesg.event != PM_EVENT_SUSPEND) - action |= ATA_EH_PM_FREEZE; - ap->eh_info.dev_action[dev->devno] |= action; - ap->eh_info.flags |= ATA_EHI_QUIET; - ata_port_schedule_eh(ap); - - spin_unlock_irqrestore(ap->lock, flags); - - /* wait for EH to do the job */ - ata_port_wait_eh(ap); - - spin_lock_irqsave(ap->lock, flags); - - /* If @sdev is still attached but the associated ATA device - * isn't suspended, the operation failed. - */ - if (sdev->sdev_state != SDEV_OFFLINE && - sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL && - !(dev->flags & ATA_DFLAG_SUSPENDED)) - rc = -EIO; - - out_unlock: - spin_unlock_irqrestore(ap->lock, flags); - out: - if (rc == 0) - sdev->sdev_gendev.power.power_state = mesg; - return rc; -} - -/** - * ata_scsi_device_resume - resume ATA device associated with sdev - * @sdev: the SCSI device to resume - * - * Request resume EH action on the ATA device associated with - * @sdev and return immediately. This enables parallel - * wakeup/spinup of devices. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0. - */ -int ata_scsi_device_resume(struct scsi_device *sdev) -{ - struct ata_port *ap = ata_shost_to_port(sdev->host); - struct ata_device *dev = ata_scsi_find_dev(ap, sdev); - struct ata_eh_info *ehi = &ap->eh_info; - unsigned long flags; - unsigned int action; - - if (!dev) - goto out; - - spin_lock_irqsave(ap->lock, flags); - - /* if @sdev is already detached, nothing to do */ - if (sdev->sdev_state == SDEV_OFFLINE || - sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) - goto out_unlock; - - /* request resume */ - action = ATA_EH_RESUME; - if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND) - __ata_ehi_hotplugged(ehi); - else - action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET; - ehi->dev_action[dev->devno] |= action; - - /* We don't want autopsy and verbose EH messages. Disable - * those if we're the only device on this link. - */ - if (ata_port_max_devices(ap) == 1) - ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; - - ata_port_schedule_eh(ap); - - out_unlock: - spin_unlock_irqrestore(ap->lock, flags); - out: - sdev->sdev_gendev.power.power_state = PMSG_ON; - return 0; -} -#endif /* CONFIG_PM */ - /** * ata_to_sense_error - convert ATA error to SCSI error * @id: ATA device number @@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev) blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); + sdev->manage_start_stop = 1; + if (dev) ata_scsi_dev_config(sdev, dev); @@ -1069,9 +944,35 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) } tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ - } else + } else { + /* XXX: This is for backward compatibility, will be + * removed. Read Documentation/feature-removal-schedule.txt + * for more info. + */ + if (ata_spindown_compat && + (system_state == SYSTEM_HALT || + system_state == SYSTEM_POWER_OFF)) { + static int warned = 0; + + if (!warned) { + spin_unlock_irq(qc->ap->lock); + ata_dev_printk(qc->dev, KERN_WARNING, + "DISK MIGHT NOT BE SPUN DOWN PROPERLY. " + "UPDATE SHUTDOWN UTILITY\n"); + ata_dev_printk(qc->dev, KERN_WARNING, + "For more info, visit " + "http://linux-ata.org/shutdown.html\n"); + warned = 1; + ssleep(5); + spin_lock_irq(qc->ap->lock); + } + scmd->result = SAM_STAT_GOOD; + return 1; + } + /* Issue ATA STANDBY IMMEDIATE command */ tf->command = ATA_CMD_STANDBYNOW1; + } /* * Standby and Idle condition timers could be implemented but that diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index d211db6b35a2..e35d13466c69 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -544,7 +544,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port) * RETURNS: * 0 on success, -errno otherwise. */ -static int ata_pci_init_bmdma(struct ata_host *host) +int ata_pci_init_bmdma(struct ata_host *host) { struct device *gdev = host->dev; struct pci_dev *pdev = to_pci_dev(gdev); @@ -566,7 +566,7 @@ static int ata_pci_init_bmdma(struct ata_host *host) } host->iomap = pcim_iomap_table(pdev); - for (i = 0; i < host->n_ports; i++) { + for (i = 0; i < 2; i++) { struct ata_port *ap = host->ports[i]; void __iomem *bmdma = host->iomap[4] + 8 * i; @@ -585,54 +585,52 @@ static int ata_pci_init_bmdma(struct ata_host *host) /** * ata_pci_init_native_host - acquire native ATA resources and init host * @host: target ATA host - * @port_mask: ports to consider * - * Acquire native PCI ATA resources for @host and initialize - * @host accordoingly. + * Acquire native PCI ATA resources for @host and initialize the + * first two ports of @host accordingly. Ports marked dummy are + * skipped and allocation failure makes the port dummy. * * LOCKING: * Inherited from calling layer (may sleep). * * RETURNS: - * 0 on success, -errno otherwise. + * 0 if at least one port is initialized, -ENODEV if no port is + * available. */ -int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) +int ata_pci_init_native_host(struct ata_host *host) { struct device *gdev = host->dev; struct pci_dev *pdev = to_pci_dev(gdev); + unsigned int mask = 0; int i, rc; - /* Discard disabled ports. Some controllers show their unused - * channels this way. Disabled ports are made dummy. - */ - for (i = 0; i < 2; i++) { - if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) { - host->ports[i]->ops = &ata_dummy_port_ops; - port_mask &= ~(1 << i); - } - } - - if (!port_mask) { - dev_printk(KERN_ERR, gdev, "no available port\n"); - return -ENODEV; - } - /* request, iomap BARs and init port addresses accordingly */ for (i = 0; i < 2; i++) { struct ata_port *ap = host->ports[i]; int base = i * 2; void __iomem * const *iomap; - if (!(port_mask & (1 << i))) + if (ata_port_is_dummy(ap)) + continue; + + /* Discard disabled ports. Some controllers show + * their unused channels this way. Disabled ports are + * made dummy. + */ + if (!ata_resources_present(pdev, i)) { + ap->ops = &ata_dummy_port_ops; continue; + } rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME); if (rc) { - dev_printk(KERN_ERR, gdev, "failed to request/iomap " - "BARs for port %d (errno=%d)\n", i, rc); + dev_printk(KERN_WARNING, gdev, + "failed to request/iomap BARs for port %d " + "(errno=%d)\n", i, rc); if (rc == -EBUSY) pcim_pin_device(pdev); - return rc; + ap->ops = &ata_dummy_port_ops; + continue; } host->iomap = iomap = pcim_iomap_table(pdev); @@ -641,6 +639,13 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) ap->ioaddr.ctl_addr = (void __iomem *) ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS); ata_std_ports(&ap->ioaddr); + + mask |= 1 << i; + } + + if (!mask) { + dev_printk(KERN_ERR, gdev, "no available native port\n"); + return -ENODEV; } return 0; @@ -649,8 +654,7 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) /** * ata_pci_prepare_native_host - helper to prepare native PCI ATA host * @pdev: target PCI device - * @ppi: array of port_info - * @n_ports: number of ports to allocate + * @ppi: array of port_info, must be enough for two ports * @r_host: out argument for the initialized ATA host * * Helper to allocate ATA host for @pdev, acquire all native PCI @@ -664,10 +668,9 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask) */ int ata_pci_prepare_native_host(struct pci_dev *pdev, const struct ata_port_info * const * ppi, - int n_ports, struct ata_host **r_host) + struct ata_host **r_host) { struct ata_host *host; - unsigned int port_mask; int rc; if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) @@ -681,11 +684,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev, goto err_out; } - port_mask = ATA_PORT_PRIMARY; - if (n_ports > 1) - port_mask |= ATA_PORT_SECONDARY; - - rc = ata_pci_init_native_host(host, port_mask); + rc = ata_pci_init_native_host(host); if (rc) goto err_out; @@ -777,8 +776,11 @@ static int ata_init_legacy_port(struct ata_port *ap, /* iomap cmd and ctl ports */ legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8); legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1); - if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) + if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) { + dev_printk(KERN_WARNING, host->dev, + "failed to map cmd/ctl ports\n"); return -ENOMEM; + } /* init IO addresses */ ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no]; @@ -792,19 +794,20 @@ static int ata_init_legacy_port(struct ata_port *ap, /** * ata_init_legacy_host - acquire legacy ATA resources and init ATA host * @host: target ATA host - * @legacy_mask: out parameter, mask indicating ports is in legacy mode * @was_busy: out parameter, indicates whether any port was busy * - * Acquire legacy ATA resources for ports. + * Acquire legacy ATA resources for the first two ports of @host + * and initialize it accordingly. Ports marked dummy are skipped + * and resource acquistion failure makes the port dummy. * * LOCKING: * Inherited from calling layer (may sleep). * * RETURNS: - * 0 on success, -errno otherwise. + * 0 if at least one port is initialized, -ENODEV if no port is + * available. */ -static int ata_init_legacy_host(struct ata_host *host, - unsigned int *legacy_mask, int *was_busy) +static int ata_init_legacy_host(struct ata_host *host, int *was_busy) { struct device *gdev = host->dev; struct ata_legacy_devres *legacy_dr; @@ -821,22 +824,23 @@ static int ata_init_legacy_host(struct ata_host *host, devres_add(gdev, legacy_dr); for (i = 0; i < 2; i++) { - *legacy_mask &= ~(1 << i); + if (ata_port_is_dummy(host->ports[i])) + continue; + rc = ata_init_legacy_port(host->ports[i], legacy_dr); if (rc == 0) legacy_dr->mask |= 1 << i; - else if (rc == -EBUSY) - (*was_busy)++; - } - - if (!legacy_dr->mask) - return -EBUSY; - - for (i = 0; i < 2; i++) - if (!(legacy_dr->mask & (1 << i))) + else { + if (rc == -EBUSY) + (*was_busy)++; host->ports[i]->ops = &ata_dummy_port_ops; + } + } - *legacy_mask |= legacy_dr->mask; + if (!legacy_dr->mask) { + dev_printk(KERN_ERR, gdev, "no available legacy port\n"); + return -ENODEV; + } devres_remove_group(gdev, NULL); return 0; @@ -875,7 +879,7 @@ static int ata_request_legacy_irqs(struct ata_host *host, legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL); BUG_ON(!legacy_dr); - for (i = 0; i < host->n_ports; i++) { + for (i = 0; i < 2; i++) { unsigned int irq; /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */ @@ -923,8 +927,7 @@ static int ata_request_legacy_irqs(struct ata_host *host, /** * ata_pci_init_one - Initialize/register PCI IDE host controller * @pdev: Controller to be initialized - * @port_info: Information from low-level host driver - * @n_ports: Number of ports attached to host controller + * @ppi: array of port_info, must be enough for two ports * * This is a helper function which can be called from a driver's * xxx_init_one() probe function if the hardware uses traditional @@ -944,26 +947,34 @@ static int ata_request_legacy_irqs(struct ata_host *host, * RETURNS: * Zero on success, negative on errno-based value on error. */ - -int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, - unsigned int n_ports) +int ata_pci_init_one(struct pci_dev *pdev, + const struct ata_port_info * const * ppi) { struct device *dev = &pdev->dev; + const struct ata_port_info *pi = NULL; struct ata_host *host = NULL; - const struct ata_port_info *port[2]; u8 mask; - unsigned int legacy_mode = 0; - int rc; + int legacy_mode = 0; + int i, rc; DPRINTK("ENTER\n"); - if (!devres_open_group(dev, NULL, GFP_KERNEL)) - return -ENOMEM; + /* look up the first valid port_info */ + for (i = 0; i < 2 && ppi[i]; i++) { + if (ppi[i]->port_ops != &ata_dummy_port_ops) { + pi = ppi[i]; + break; + } + } - BUG_ON(n_ports < 1 || n_ports > 2); + if (!pi) { + dev_printk(KERN_ERR, &pdev->dev, + "no valid port_info specified\n"); + return -EINVAL; + } - port[0] = port_info[0]; - port[1] = (n_ports > 1) ? port_info[1] : NULL; + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return -ENOMEM; /* FIXME: Really for ATA it isn't safe because the device may be multi-purpose and we want to leave it alone if it was already @@ -984,7 +995,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); mask = (1 << 2) | (1 << 0); if ((tmp8 & mask) != mask) - legacy_mode = (1 << 3); + legacy_mode = 1; #if defined(CONFIG_NO_ATA_LEGACY) /* Some platforms with PCI limits cannot address compat port space. In that case we punt if their firmware has @@ -998,7 +1009,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, } /* alloc and init host */ - host = ata_host_alloc_pinfo(dev, port, n_ports); + host = ata_host_alloc_pinfo(dev, ppi, 2); if (!host) { dev_printk(KERN_ERR, &pdev->dev, "failed to allocate ATA host\n"); @@ -1007,19 +1018,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, } if (!legacy_mode) { - unsigned int port_mask; - - port_mask = ATA_PORT_PRIMARY; - if (n_ports > 1) - port_mask |= ATA_PORT_SECONDARY; - - rc = ata_pci_init_native_host(host, port_mask); + rc = ata_pci_init_native_host(host); if (rc) goto err_out; } else { int was_busy = 0; - rc = ata_init_legacy_host(host, &legacy_mode, &was_busy); + rc = ata_init_legacy_host(host, &was_busy); if (was_busy) pcim_pin_device(pdev); if (rc) @@ -1040,8 +1045,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, goto err_out; if (!legacy_mode) - rc = devm_request_irq(dev, pdev->irq, - port_info[0]->port_ops->irq_handler, + rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler, IRQF_SHARED, DRV_NAME, host); else { irq_handler_t handler[2] = { host->ops->irq_handler, @@ -1055,7 +1059,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, goto err_out; /* register */ - rc = ata_host_register(host, port_info[0]->sht); + rc = ata_host_register(host, pi->sht); if (rc) goto err_out; diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 5f4d40cd3288..8b71b73a199c 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -58,6 +58,7 @@ extern int atapi_enabled; extern int atapi_dmadir; extern int libata_fua; extern int libata_noacpi; +extern int ata_spindown_compat; extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, u64 block, u32 n_block, unsigned int tf_flags, @@ -96,15 +97,15 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct ata_port *ata_port_alloc(struct ata_host *host); /* libata-acpi.c */ -#ifdef CONFIG_SATA_ACPI +#ifdef CONFIG_ATA_ACPI extern int ata_acpi_exec_tfs(struct ata_port *ap); -extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix); +extern int ata_acpi_push_id(struct ata_device *dev); #else static inline int ata_acpi_exec_tfs(struct ata_port *ap) { return 0; } -static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix) +static inline int ata_acpi_push_id(struct ata_device *dev) { return 0; } diff --git a/trunk/drivers/ata/pata_ali.c b/trunk/drivers/ata/pata_ali.c index d40edebb510a..3c55a5ff74c7 100644 --- a/trunk/drivers/ata/pata_ali.c +++ b/trunk/drivers/ata/pata_ali.c @@ -291,10 +291,6 @@ static struct scsi_host_template ali_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; /* @@ -522,14 +518,14 @@ static void ali_init_chipset(struct pci_dev *pdev) static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info_early = { + static const struct ata_port_info info_early = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &ali_early_port_ops }; /* Revision 0x20 added DMA */ - static struct ata_port_info info_20 = { + static const struct ata_port_info info_20 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, @@ -537,7 +533,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_20_port_ops }; /* Revision 0x20 with support logic added UDMA */ - static struct ata_port_info info_20_udma = { + static const struct ata_port_info info_20_udma = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, @@ -546,7 +542,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_20_port_ops }; /* Revision 0xC2 adds UDMA66 */ - static struct ata_port_info info_c2 = { + static const struct ata_port_info info_c2 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, @@ -555,7 +551,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_c2_port_ops }; /* Revision 0xC3 is UDMA100 */ - static struct ata_port_info info_c3 = { + static const struct ata_port_info info_c3 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, @@ -564,7 +560,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_c2_port_ops }; /* Revision 0xC4 is UDMA133 */ - static struct ata_port_info info_c4 = { + static const struct ata_port_info info_c4 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, @@ -573,7 +569,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_c2_port_ops }; /* Revision 0xC5 is UDMA133 with LBA48 DMA */ - static struct ata_port_info info_c5 = { + static const struct ata_port_info info_c5 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -582,7 +578,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &ali_c5_port_ops }; - static struct ata_port_info *port_info[2]; + const struct ata_port_info *ppi[] = { NULL, NULL }; u8 rev, tmp; struct pci_dev *isa_bridge; @@ -594,17 +590,17 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) */ if (rev < 0x20) { - port_info[0] = port_info[1] = &info_early; + ppi[0] = &info_early; } else if (rev < 0xC2) { - port_info[0] = port_info[1] = &info_20; + ppi[0] = &info_20; } else if (rev == 0xC2) { - port_info[0] = port_info[1] = &info_c2; + ppi[0] = &info_c2; } else if (rev == 0xC3) { - port_info[0] = port_info[1] = &info_c3; + ppi[0] = &info_c3; } else if (rev == 0xC4) { - port_info[0] = port_info[1] = &info_c4; + ppi[0] = &info_c4; } else - port_info[0] = port_info[1] = &info_c5; + ppi[0] = &info_c5; ali_init_chipset(pdev); @@ -613,10 +609,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Are we paired with a UDMA capable chip */ pci_read_config_byte(isa_bridge, 0x5E, &tmp); if ((tmp & 0x1E) == 0x12) - port_info[0] = port_info[1] = &info_20_udma; + ppi[0] = &info_20_udma; pci_dev_put(isa_bridge); } - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_amd.c b/trunk/drivers/ata/pata_amd.c index 67c7e87dec04..b439351f1fd3 100644 --- a/trunk/drivers/ata/pata_amd.c +++ b/trunk/drivers/ata/pata_amd.c @@ -324,10 +324,6 @@ static struct scsi_host_template amd_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations amd33_port_ops = { @@ -542,7 +538,7 @@ static struct ata_port_operations nv133_port_ops = { static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info[10] = { + static const struct ata_port_info info[10] = { { /* 0: AMD 7401 */ .sht = &amd_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -624,7 +620,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &amd100_port_ops } }; - static struct ata_port_info *port_info[2]; + const struct ata_port_info *ppi[] = { NULL, NULL }; static int printed_version; int type = id->driver_data; u8 rev; @@ -656,9 +652,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ata_pci_clear_simplex(pdev); /* And fire it up */ - - port_info[0] = port_info[1] = &info[type]; - return ata_pci_init_one(pdev, port_info, 2); + ppi[0] = &info[type]; + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_artop.c b/trunk/drivers/ata/pata_artop.c index ef51940c3adb..9861059dd673 100644 --- a/trunk/drivers/ata/pata_artop.c +++ b/trunk/drivers/ata/pata_artop.c @@ -414,7 +414,7 @@ static const struct ata_port_operations artop6260_ops = { static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { static int printed_version; - static struct ata_port_info info_6210 = { + static const struct ata_port_info info_6210 = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -422,7 +422,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA2, .port_ops = &artop6210_ops, }; - static struct ata_port_info info_626x = { + static const struct ata_port_info info_626x = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -430,7 +430,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA4, .port_ops = &artop6260_ops, }; - static struct ata_port_info info_626x_fast = { + static const struct ata_port_info info_626x_fast = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -438,32 +438,30 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA5, .port_ops = &artop6260_ops, }; - struct ata_port_info *port_info[2]; - struct ata_port_info *info = NULL; - int ports = 2; + const struct ata_port_info *ppi[] = { NULL, NULL }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); if (id->driver_data == 0) { /* 6210 variant */ - info = &info_6210; + ppi[0] = &info_6210; + ppi[1] = &ata_dummy_port_info; /* BIOS may have left us in UDMA, clear it before libata probe */ pci_write_config_byte(pdev, 0x54, 0); /* For the moment (also lacks dsc) */ printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n"); printk(KERN_WARNING "Secondary ATA ports will not be activated.\n"); - ports = 1; } else if (id->driver_data == 1) /* 6260 */ - info = &info_626x; + ppi[0] = &info_626x; else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ unsigned long io = pci_resource_start(pdev, 4); u8 reg; - info = &info_626x; + ppi[0] = &info_626x; if (inb(io) & 0x10) - info = &info_626x_fast; + ppi[0] = &info_626x_fast; /* Mac systems come up with some registers not set as we will need them */ @@ -484,10 +482,9 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) } - BUG_ON(info == NULL); + BUG_ON(ppi[0] == NULL); - port_info[0] = port_info[1] = info; - return ata_pci_init_one(pdev, port_info, ports); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id artop_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c index 21515381b5b3..844914681a2a 100644 --- a/trunk/drivers/ata/pata_atiixp.c +++ b/trunk/drivers/ata/pata_atiixp.c @@ -229,10 +229,6 @@ static struct scsi_host_template atiixp_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations atiixp_port_ops = { @@ -272,7 +268,7 @@ static struct ata_port_operations atiixp_port_ops = { static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &atiixp_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -280,8 +276,8 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x3F, .port_ops = &atiixp_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; - return ata_pci_init_one(dev, port_info, 2); + const struct ata_port_info *ppi[] = { &info, NULL }; + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id atiixp[] = { diff --git a/trunk/drivers/ata/pata_cmd640.c b/trunk/drivers/ata/pata_cmd640.c index 2105985a8013..ed00fa9d53be 100644 --- a/trunk/drivers/ata/pata_cmd640.c +++ b/trunk/drivers/ata/pata_cmd640.c @@ -181,10 +181,6 @@ static struct scsi_host_template cmd640_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cmd640_port_ops = { @@ -253,17 +249,16 @@ static void cmd640_hardware_init(struct pci_dev *pdev) static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &cmd640_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &cmd640_port_ops }; - - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; cmd640_hardware_init(pdev); - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static int cmd640_reinit_one(struct pci_dev *pdev) diff --git a/trunk/drivers/ata/pata_cmd64x.c b/trunk/drivers/ata/pata_cmd64x.c index 3989cc577fcd..2a79b335cfcc 100644 --- a/trunk/drivers/ata/pata_cmd64x.c +++ b/trunk/drivers/ata/pata_cmd64x.c @@ -266,10 +266,6 @@ static struct scsi_host_template cmd64x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cmd64x_port_ops = { @@ -381,7 +377,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { u32 class_rev; - static struct ata_port_info cmd_info[6] = { + static const struct ata_port_info cmd_info[6] = { { /* CMD 643 - no UDMA */ .sht = &cmd64x_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -428,11 +424,9 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &cmd648_port_ops } }; - static struct ata_port_info *port_info[2], *info; + const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL }; u8 mrdmode; - info = &cmd_info[id->driver_data]; - pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xFF; @@ -442,10 +436,10 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (pdev->device == PCI_DEVICE_ID_CMD_646) { /* Does UDMA work ? */ if (class_rev > 4) - info = &cmd_info[2]; + ppi[0] = &cmd_info[2]; /* Early rev with other problems ? */ else if (class_rev == 1) - info = &cmd_info[3]; + ppi[0] = &cmd_info[3]; } pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); @@ -461,8 +455,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_write_config_byte(pdev, UDIDETCR0, 0xF0); #endif - port_info[0] = port_info[1] = info; - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_cs5520.c b/trunk/drivers/ata/pata_cs5520.c index 79bef0d1fad3..83bcc5b32597 100644 --- a/trunk/drivers/ata/pata_cs5520.c +++ b/trunk/drivers/ata/pata_cs5520.c @@ -155,10 +155,6 @@ static struct scsi_host_template cs5520_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cs5520_port_ops = { diff --git a/trunk/drivers/ata/pata_cs5530.c b/trunk/drivers/ata/pata_cs5530.c index 29642d5ee189..1b67923d7a4e 100644 --- a/trunk/drivers/ata/pata_cs5530.c +++ b/trunk/drivers/ata/pata_cs5530.c @@ -176,10 +176,6 @@ static struct scsi_host_template cs5530_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cs5530_port_ops = { @@ -339,7 +335,7 @@ static int cs5530_init_chip(void) static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &cs5530_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -348,23 +344,23 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &cs5530_port_ops }; /* The docking connector doesn't do UDMA, and it seems not MWDMA */ - static struct ata_port_info info_palmax_secondary = { + static const struct ata_port_info info_palmax_secondary = { .sht = &cs5530_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &cs5530_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; /* Chip initialisation */ if (cs5530_init_chip()) return -ENODEV; if (cs5530_is_palmax()) - port_info[1] = &info_palmax_secondary; + ppi[1] = &info_palmax_secondary; /* Now kick off ATA set up */ - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_cs5535.c b/trunk/drivers/ata/pata_cs5535.c index 22006ae71941..f37d4cd812a1 100644 --- a/trunk/drivers/ata/pata_cs5535.c +++ b/trunk/drivers/ata/pata_cs5535.c @@ -173,10 +173,6 @@ static struct scsi_host_template cs5535_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cs5535_port_ops = { @@ -227,7 +223,7 @@ static struct ata_port_operations cs5535_port_ops = { static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &cs5535_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -235,7 +231,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x1f, .port_ops = &cs5535_port_ops }; - struct ata_port_info *ports[1] = { &info }; + const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; u32 timings, dummy; @@ -247,7 +243,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) rdmsr(ATAC_CH0D1_PIO, timings, dummy); if (CS5535_BAD_PIO(timings)) wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); - return ata_pci_init_one(dev, ports, 1); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id cs5535[] = { diff --git a/trunk/drivers/ata/pata_cypress.c b/trunk/drivers/ata/pata_cypress.c index 6ec049c3b1dc..27b9f29c01e3 100644 --- a/trunk/drivers/ata/pata_cypress.c +++ b/trunk/drivers/ata/pata_cypress.c @@ -125,10 +125,6 @@ static struct scsi_host_template cy82c693_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations cy82c693_port_ops = { @@ -169,14 +165,14 @@ static struct ata_port_operations cy82c693_port_ops = { static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &cy82c693_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &cy82c693_port_ops }; - static struct ata_port_info *port_info[1] = { &info }; + const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; /* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the moment we don't handle the secondary. FIXME */ @@ -184,7 +180,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i if (PCI_FUNC(pdev->devfn) != 1) return -ENODEV; - return ata_pci_init_one(pdev, port_info, 1); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id cy82c693[] = { diff --git a/trunk/drivers/ata/pata_efar.c b/trunk/drivers/ata/pata_efar.c index d0f52e034906..079248a9b460 100644 --- a/trunk/drivers/ata/pata_efar.c +++ b/trunk/drivers/ata/pata_efar.c @@ -247,10 +247,6 @@ static struct scsi_host_template efar_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations efar_ops = { @@ -305,7 +301,7 @@ static const struct ata_port_operations efar_ops = { static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &efar_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -313,13 +309,13 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) .udma_mask = 0x0f, /* UDMA 66 */ .port_ops = &efar_ops, }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id efar_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index e64e05e5c7fe..c6c8a8bb06d0 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -331,10 +331,6 @@ static struct scsi_host_template hpt36x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; /* @@ -421,7 +417,7 @@ static void hpt36x_init_chipset(struct pci_dev *dev) static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info_hpt366 = { + static const struct ata_port_info info_hpt366 = { .sht = &hpt36x_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -429,7 +425,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x1f, .port_ops = &hpt366_port_ops }; - struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366}; + struct ata_port_info info = info_hpt366; + const struct ata_port_info *ppi[] = { &info, NULL }; u32 class_rev; u32 reg1; @@ -450,17 +447,17 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* info_hpt366 is safe against re-entry so we can scribble on it */ switch((reg1 & 0x700) >> 8) { case 5: - info_hpt366.private_data = &hpt366_40; + info.private_data = &hpt366_40; break; case 9: - info_hpt366.private_data = &hpt366_25; + info.private_data = &hpt366_25; break; default: - info_hpt366.private_data = &hpt366_33; + info.private_data = &hpt366_33; break; } /* Now kick off ATA set up */ - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index 1614e8c822a4..5a0a410654e2 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -887,7 +887,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { /* HPT370 - UDMA100 */ - static struct ata_port_info info_hpt370 = { + static const struct ata_port_info info_hpt370 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -896,7 +896,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt370_port_ops }; /* HPT370A - UDMA100 */ - static struct ata_port_info info_hpt370a = { + static const struct ata_port_info info_hpt370a = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -905,7 +905,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt370a_port_ops }; /* HPT370 - UDMA100 */ - static struct ata_port_info info_hpt370_33 = { + static const struct ata_port_info info_hpt370_33 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -914,7 +914,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt370_port_ops }; /* HPT370A - UDMA100 */ - static struct ata_port_info info_hpt370a_33 = { + static const struct ata_port_info info_hpt370a_33 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -923,7 +923,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt370a_port_ops }; /* HPT371, 372 and friends - UDMA133 */ - static struct ata_port_info info_hpt372 = { + static const struct ata_port_info info_hpt372 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -932,7 +932,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt372_port_ops }; /* HPT371, 372 and friends - UDMA100 at 50MHz clock */ - static struct ata_port_info info_hpt372_50 = { + static const struct ata_port_info info_hpt372_50 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -941,7 +941,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) .port_ops = &hpt372_port_ops }; /* HPT374 - UDMA133 */ - static struct ata_port_info info_hpt374 = { + static const struct ata_port_info info_hpt374 = { .sht = &hpt37x_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -951,9 +951,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) }; static const int MHz[4] = { 33, 40, 50, 66 }; - - struct ata_port_info *port_info[2]; - struct ata_port_info *port; + const struct ata_port_info *port; + void *private_data = NULL; + struct ata_port_info port_info; + const struct ata_port_info *ppi[] = { &port_info, NULL }; u8 irqmask; u32 class_rev; @@ -1124,13 +1125,13 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; } if (clock_slot == 3) - port->private_data = (void *)hpt37x_timings_66; + private_data = (void *)hpt37x_timings_66; else - port->private_data = (void *)hpt37x_timings_50; + private_data = (void *)hpt37x_timings_50; printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]); } else { - port->private_data = (void *)chip_table->clocks[clock_slot]; + private_data = (void *)chip_table->clocks[clock_slot]; /* * Perform a final fixup. Note that we will have used the * DPLL on the HPT372 which means we don't have to worry @@ -1144,9 +1145,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); } - port_info[0] = port_info[1] = port; /* Now kick off ATA set up */ - return ata_pci_init_one(dev, port_info, 2); + port_info = *port; + port_info.private_data = private_data; + + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id hpt37x[] = { diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index ea1037d67860..f25154aed75d 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -488,7 +488,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) { /* HPT372N and friends - UDMA133 */ - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &hpt3x2n_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -496,8 +496,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x7f, .port_ops = &hpt3x2n_port_ops }; - struct ata_port_info *port_info[2]; - struct ata_port_info *port = &info; + struct ata_port_info port = info; + const struct ata_port_info *ppi[] = { &port, NULL }; u8 irqmask; u32 class_rev; @@ -585,9 +585,9 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* Set our private data up. We only need a few flags so we use it directly */ - port->private_data = NULL; + port.private_data = NULL; if (pci_mhz > 60) { - port->private_data = (void *)PCI66; + port.private_data = (void *)PCI66; /* * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in * the MISC. register to stretch the UltraDMA Tss timing. @@ -598,8 +598,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) } /* Now kick off ATA set up */ - port_info[0] = port_info[1] = port; - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id hpt3x2n[] = { diff --git a/trunk/drivers/ata/pata_hpt3x3.c b/trunk/drivers/ata/pata_hpt3x3.c index ac28ec8c50aa..bbabe7902fbb 100644 --- a/trunk/drivers/ata/pata_hpt3x3.c +++ b/trunk/drivers/ata/pata_hpt3x3.c @@ -100,10 +100,6 @@ static struct scsi_host_template hpt3x3_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations hpt3x3_port_ops = { @@ -175,7 +171,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev) static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &hpt3x3_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -183,11 +179,11 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x07, .port_ops = &hpt3x3_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; hpt3x3_init_chipset(dev); /* Now kick off ATA set up */ - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_it8213.c b/trunk/drivers/ata/pata_it8213.c index 17bf9f3ed013..a769952646e1 100644 --- a/trunk/drivers/ata/pata_it8213.c +++ b/trunk/drivers/ata/pata_it8213.c @@ -257,10 +257,6 @@ static struct scsi_host_template it8213_sht = { .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations it8213_ops = { @@ -315,7 +311,7 @@ static const struct ata_port_operations it8213_ops = { static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &it8213_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -323,14 +319,14 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en .udma_mask = 0x1f, /* UDMA 100 */ .port_ops = &it8213_ops, }; - static struct ata_port_info *port_info[2] = { &info, &info }; + /* Current IT8213 stuff is single port */ + const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - /* Current IT8213 stuff is single port */ - return ata_pci_init_one(pdev, port_info, 1); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id it8213_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_it821x.c b/trunk/drivers/ata/pata_it821x.c index f1f8cec8c224..ff9a6fd36657 100644 --- a/trunk/drivers/ata/pata_it821x.c +++ b/trunk/drivers/ata/pata_it821x.c @@ -620,10 +620,6 @@ static struct scsi_host_template it821x_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations it821x_smart_port_ops = { @@ -722,14 +718,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { u8 conf; - static struct ata_port_info info_smart = { + static const struct ata_port_info info_smart = { .sht = &it821x_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &it821x_smart_port_ops }; - static struct ata_port_info info_passthru = { + static const struct ata_port_info info_passthru = { .sht = &it821x_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -737,8 +733,8 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = 0x7f, .port_ops = &it821x_passthru_port_ops }; - static struct ata_port_info *port_info[2]; + const struct ata_port_info *ppi[] = { NULL, NULL }; static char *mode[2] = { "pass through", "smart" }; /* Force the card into bypass mode if so requested */ @@ -751,11 +747,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]); if (conf == 0) - port_info[0] = port_info[1] = &info_passthru; + ppi[0] = &info_passthru; else - port_info[0] = port_info[1] = &info_smart; + ppi[0] = &info_smart; - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_ixp4xx_cf.c b/trunk/drivers/ata/pata_ixp4xx_cf.c index 420c343e5711..b994351fbcd0 100644 --- a/trunk/drivers/ata/pata_ixp4xx_cf.c +++ b/trunk/drivers/ata/pata_ixp4xx_cf.c @@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_ready(dev)) { + if (ata_dev_enabled(dev)) { ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; diff --git a/trunk/drivers/ata/pata_jmicron.c b/trunk/drivers/ata/pata_jmicron.c index 1daf78ac6efb..8d799e87f752 100644 --- a/trunk/drivers/ata/pata_jmicron.c +++ b/trunk/drivers/ata/pata_jmicron.c @@ -138,10 +138,6 @@ static struct scsi_host_template jmicron_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations jmicron_ops = { @@ -195,7 +191,7 @@ static const struct ata_port_operations jmicron_ops = { static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &jmicron_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -205,9 +201,9 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i .port_ops = &jmicron_ops, }; - struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id jmicron_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_marvell.c b/trunk/drivers/ata/pata_marvell.c index 837b7fe77dc7..edbfe0dbbf78 100644 --- a/trunk/drivers/ata/pata_marvell.c +++ b/trunk/drivers/ata/pata_marvell.c @@ -107,10 +107,6 @@ static struct scsi_host_template marvell_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations marvell_ops = { @@ -165,7 +161,7 @@ static const struct ata_port_operations marvell_ops = { static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &marvell_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -175,7 +171,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i .port_ops = &marvell_ops, }; - static struct ata_port_info info_sata = { + static const struct ata_port_info info_sata = { .sht = &marvell_sht, /* Slave possible as its magically mapped not real */ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -186,13 +182,12 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i .port_ops = &marvell_ops, }; - struct ata_port_info *port_info[2] = { &info, &info_sata }; - int n_port = 2; + const struct ata_port_info *ppi[] = { &info, &info_sata }; if (pdev->device == 0x6101) - n_port = 1; + ppi[1] = &ata_dummy_port_info; - return ata_pci_init_one(pdev, port_info, n_port); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id marvell_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_mpc52xx.c b/trunk/drivers/ata/pata_mpc52xx.c index 9587a89f9683..368fac7d168b 100644 --- a/trunk/drivers/ata/pata_mpc52xx.c +++ b/trunk/drivers/ata/pata_mpc52xx.c @@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx_ata_sht = { .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = ata_scsi_slave_config, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static struct ata_port_operations mpc52xx_ata_port_ops = { diff --git a/trunk/drivers/ata/pata_mpiix.c b/trunk/drivers/ata/pata_mpiix.c index 3bfbd495f643..4ea42838297e 100644 --- a/trunk/drivers/ata/pata_mpiix.c +++ b/trunk/drivers/ata/pata_mpiix.c @@ -165,10 +165,6 @@ static struct scsi_host_template mpiix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations mpiix_port_ops = { diff --git a/trunk/drivers/ata/pata_netcell.c b/trunk/drivers/ata/pata_netcell.c index dbba5b77d79c..81f563458666 100644 --- a/trunk/drivers/ata/pata_netcell.c +++ b/trunk/drivers/ata/pata_netcell.c @@ -37,10 +37,6 @@ static struct scsi_host_template netcell_sht = { .slave_destroy = ata_scsi_slave_destroy, /* Use standard CHS mapping rules */ .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations netcell_ops = { @@ -96,7 +92,7 @@ static const struct ata_port_operations netcell_ops = { static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &netcell_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, /* Actually we don't really care about these as the @@ -106,7 +102,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e .udma_mask = 0x3f, /* UDMA 133 */ .port_ops = &netcell_ops, }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *port_info[] = { &info, NULL }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, @@ -116,7 +112,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e ata_pci_clear_simplex(pdev); /* And let the library code do the work */ - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, port_info); } static const struct pci_device_id netcell_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_ns87410.c b/trunk/drivers/ata/pata_ns87410.c index ebc58a907d26..ea70ec744879 100644 --- a/trunk/drivers/ata/pata_ns87410.c +++ b/trunk/drivers/ata/pata_ns87410.c @@ -158,10 +158,6 @@ static struct scsi_host_template ns87410_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations ns87410_port_ops = { @@ -195,14 +191,14 @@ static struct ata_port_operations ns87410_port_ops = { static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &ns87410_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x0F, .port_ops = &ns87410_port_ops }; - static struct ata_port_info *port_info[2] = {&info, &info}; - return ata_pci_init_one(dev, port_info, 2); + const struct ata_port_info *ppi[] = { &info, NULL }; + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id ns87410[] = { diff --git a/trunk/drivers/ata/pata_oldpiix.c b/trunk/drivers/ata/pata_oldpiix.c index 4d75d32e5826..29c23ddd6550 100644 --- a/trunk/drivers/ata/pata_oldpiix.c +++ b/trunk/drivers/ata/pata_oldpiix.c @@ -234,10 +234,6 @@ static struct scsi_host_template oldpiix_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations oldpiix_pata_ops = { @@ -293,20 +289,20 @@ static const struct ata_port_operations oldpiix_pata_ops = { static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &oldpiix_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma1-2 */ .port_ops = &oldpiix_pata_ops, }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id oldpiix_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_opti.c b/trunk/drivers/ata/pata_opti.c index 0af8a2c77cc9..1c44653e1e06 100644 --- a/trunk/drivers/ata/pata_opti.c +++ b/trunk/drivers/ata/pata_opti.c @@ -179,10 +179,6 @@ static struct scsi_host_template opti_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations opti_port_ops = { @@ -220,19 +216,19 @@ static struct ata_port_operations opti_port_ops = { static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &opti_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &opti_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; static int printed_version; if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id opti[] = { diff --git a/trunk/drivers/ata/pata_optidma.c b/trunk/drivers/ata/pata_optidma.c index 2843e480f216..3093b02286ce 100644 --- a/trunk/drivers/ata/pata_optidma.c +++ b/trunk/drivers/ata/pata_optidma.c @@ -363,10 +363,6 @@ static struct scsi_host_template optidma_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations optidma_port_ops = { @@ -486,14 +482,14 @@ static int optiplus_with_udma(struct pci_dev *pdev) static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info_82c700 = { + static const struct ata_port_info info_82c700 = { .sht = &optidma_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &optidma_port_ops }; - static struct ata_port_info info_82c700_udma = { + static const struct ata_port_info info_82c700_udma = { .sht = &optidma_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -501,8 +497,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x07, .port_ops = &optiplus_port_ops }; - static struct ata_port_info *port_info[2]; - struct ata_port_info *info = &info_82c700; + const struct ata_port_info *ppi[] = { &info_82c700, NULL }; static int printed_version; if (!printed_version++) @@ -514,10 +509,9 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_clock = inb(0x1F5) & 1; /* 0 = 33Mhz, 1 = 25Mhz */ if (optiplus_with_udma(dev)) - info = &info_82c700_udma; + ppi[0] = &info_82c700_udma; - port_info[0] = port_info[1] = info; - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id optidma[] = { diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index 11245e331f77..4d44c7555db1 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -397,6 +397,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), + PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), diff --git a/trunk/drivers/ata/pata_pdc202xx_old.c b/trunk/drivers/ata/pata_pdc202xx_old.c index ee636beb05e1..edbaf9d653b8 100644 --- a/trunk/drivers/ata/pata_pdc202xx_old.c +++ b/trunk/drivers/ata/pata_pdc202xx_old.c @@ -244,10 +244,6 @@ static struct scsi_host_template pdc202xx_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations pdc2024x_port_ops = { @@ -321,7 +317,7 @@ static struct ata_port_operations pdc2026x_port_ops = { static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info[3] = { + static const struct ata_port_info info[3] = { { .sht = &pdc202xx_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -348,9 +344,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id } }; - static struct ata_port_info *port_info[2]; - - port_info[0] = port_info[1] = &info[id->driver_data]; + const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL }; if (dev->device == PCI_DEVICE_ID_PROMISE_20265) { struct pci_dev *bridge = dev->bus->self; @@ -362,7 +356,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id return -ENODEV; } } - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id pdc202xx[] = { diff --git a/trunk/drivers/ata/pata_platform.c b/trunk/drivers/ata/pata_platform.c index a0a650c7f272..1f6384895a4f 100644 --- a/trunk/drivers/ata/pata_platform.c +++ b/trunk/drivers/ata/pata_platform.c @@ -48,6 +48,8 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse return 0; } +static int ata_dummy_ret0(struct ata_port *ap) { return 0; } + static struct scsi_host_template pata_platform_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -91,7 +93,7 @@ static struct ata_port_operations pata_platform_port_ops = { .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, - .port_start = ata_port_start, + .port_start = ata_dummy_ret0, }; static void pata_platform_setup_port(struct ata_ioports *ioaddr, diff --git a/trunk/drivers/ata/pata_radisys.c b/trunk/drivers/ata/pata_radisys.c index 1c54673e008d..ba96b54f5b87 100644 --- a/trunk/drivers/ata/pata_radisys.c +++ b/trunk/drivers/ata/pata_radisys.c @@ -200,10 +200,6 @@ static struct scsi_host_template radisys_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations radisys_pata_ops = { @@ -259,7 +255,7 @@ static const struct ata_port_operations radisys_pata_ops = { static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &radisys_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -267,13 +263,13 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e .udma_mask = 0x14, /* UDMA33/66 only */ .port_ops = &radisys_pata_ops, }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id radisys_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_rz1000.c b/trunk/drivers/ata/pata_rz1000.c index 85c45290eeee..2bfd7ef42af5 100644 --- a/trunk/drivers/ata/pata_rz1000.c +++ b/trunk/drivers/ata/pata_rz1000.c @@ -40,7 +40,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_ready(dev)) { + if (ata_dev_enabled(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; @@ -69,10 +69,6 @@ static struct scsi_host_template rz1000_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations rz1000_port_ops = { @@ -135,22 +131,20 @@ static int rz1000_fifo_disable(struct pci_dev *pdev) static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_port_info *port_info[2]; - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &rz1000_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &rz1000_port_ops }; + const struct ata_port_info *ppi[] = { &info, NULL }; if (!printed_version++) printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); - if (rz1000_fifo_disable(pdev) == 0) { - port_info[0] = &info; - port_info[1] = &info; - return ata_pci_init_one(pdev, port_info, 2); - } + if (rz1000_fifo_disable(pdev) == 0) + return ata_pci_init_one(pdev, ppi); + printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); /* Not safe to use so skip */ return -ENODEV; diff --git a/trunk/drivers/ata/pata_sc1200.c b/trunk/drivers/ata/pata_sc1200.c index 66e8ff467c8d..225013ecf4b6 100644 --- a/trunk/drivers/ata/pata_sc1200.c +++ b/trunk/drivers/ata/pata_sc1200.c @@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations sc1200_port_ops = { @@ -247,7 +243,7 @@ static struct ata_port_operations sc1200_port_ops = { static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &sc1200_sht, .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -255,10 +251,10 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) .udma_mask = 0x07, .port_ops = &sc1200_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; - /* Can't enable port 2 yet, see top comments */ - return ata_pci_init_one(dev, port_info, 1); + const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; + + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id sc1200[] = { diff --git a/trunk/drivers/ata/pata_scc.c b/trunk/drivers/ata/pata_scc.c index 203f463ac39f..cca3aa225efe 100644 --- a/trunk/drivers/ata/pata_scc.c +++ b/trunk/drivers/ata/pata_scc.c @@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations scc_pata_ops = { diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c index b6e020383dd9..dee6e211949d 100644 --- a/trunk/drivers/ata/pata_serverworks.c +++ b/trunk/drivers/ata/pata_serverworks.c @@ -315,10 +315,6 @@ static struct scsi_host_template serverworks_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations serverworks_osb4_port_ops = { @@ -479,8 +475,7 @@ static void serverworks_fixup_ht1000(struct pci_dev *pdev) static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - int ports = 2; - static struct ata_port_info info[4] = { + static const struct ata_port_info info[4] = { { /* OSB4 */ .sht = &serverworks_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -511,8 +506,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id .port_ops = &serverworks_csb_port_ops } }; - static struct ata_port_info *port_info[2]; - struct ata_port_info *devinfo = &info[id->driver_data]; + const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL }; /* Force master latency timer to 64 PCI clocks */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); @@ -521,7 +515,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { /* Select non UDMA capable OSB4 if we can't do fixups */ if ( serverworks_fixup_osb4(pdev) < 0) - devinfo = &info[1]; + ppi[0] = &info[1]; } /* setup CSB5/CSB6 : South Bridge and IDE option RAID */ else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) || @@ -531,11 +525,11 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id /* If the returned btr is the newer revision then select the right info block */ if (serverworks_fixup_csb(pdev) == 3) - devinfo = &info[3]; + ppi[0] = &info[3]; /* Is this the 3rd channel CSB6 IDE ? */ if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) - ports = 1; + ppi[1] = &ata_dummy_port_info; } /* setup HT1000E */ else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) @@ -544,8 +538,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ata_pci_clear_simplex(pdev); - port_info[0] = port_info[1] = devinfo; - return ata_pci_init_one(pdev, port_info, ports); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_sil680.c b/trunk/drivers/ata/pata_sil680.c index a5886f061c0b..440e2cb6ee75 100644 --- a/trunk/drivers/ata/pata_sil680.c +++ b/trunk/drivers/ata/pata_sil680.c @@ -232,10 +232,6 @@ static struct scsi_host_template sil680_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static struct ata_port_operations sil680_port_ops = { @@ -345,7 +341,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev) static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &sil680_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -353,7 +349,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = 0x7f, .port_ops = &sil680_port_ops }; - static struct ata_port_info info_slow = { + static const struct ata_port_info info_slow = { .sht = &sil680_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, @@ -361,7 +357,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = 0x3f, .port_ops = &sil680_port_ops }; - static struct ata_port_info *port_info[2] = {&info, &info}; + const struct ata_port_info *ppi[] = { &info, NULL }; static int printed_version; if (!printed_version++) @@ -370,12 +366,12 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) switch(sil680_init_chip(pdev)) { case 0: - port_info[0] = port_info[1] = &info_slow; + ppi[0] = &info_slow; break; case 0x30: return -ENODEV; } - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/pata_sis.c b/trunk/drivers/ata/pata_sis.c index f5838cc11728..f2231267e011 100644 --- a/trunk/drivers/ata/pata_sis.c +++ b/trunk/drivers/ata/pata_sis.c @@ -38,8 +38,8 @@ #define DRV_VERSION "0.5.1" struct sis_chipset { - u16 device; /* PCI host ID */ - struct ata_port_info *info; /* Info block */ + u16 device; /* PCI host ID */ + const struct ata_port_info *info; /* Info block */ /* Probably add family, cable detect type etc here to clean up code later */ }; @@ -524,10 +524,6 @@ static struct scsi_host_template sis_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static const struct ata_port_operations sis_133_ops = { @@ -700,7 +696,7 @@ static const struct ata_port_operations sis_old_ops = { .port_start = ata_port_start, }; -static struct ata_port_info sis_info = { +static const struct ata_port_info sis_info = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -708,7 +704,7 @@ static struct ata_port_info sis_info = { .udma_mask = 0, .port_ops = &sis_old_ops, }; -static struct ata_port_info sis_info33 = { +static const struct ata_port_info sis_info33 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -716,35 +712,35 @@ static struct ata_port_info sis_info33 = { .udma_mask = ATA_UDMA2, /* UDMA 33 */ .port_ops = &sis_old_ops, }; -static struct ata_port_info sis_info66 = { +static const struct ata_port_info sis_info66 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA4, /* UDMA 66 */ .port_ops = &sis_66_ops, }; -static struct ata_port_info sis_info100 = { +static const struct ata_port_info sis_info100 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA5, .port_ops = &sis_100_ops, }; -static struct ata_port_info sis_info100_early = { +static const struct ata_port_info sis_info100_early = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .udma_mask = ATA_UDMA5, .pio_mask = 0x1f, /* pio0-4 */ .port_ops = &sis_66_ops, }; -struct ata_port_info sis_info133 = { +const struct ata_port_info sis_info133 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &sis_133_ops, }; -static struct ata_port_info sis_info133_early = { +static const struct ata_port_info sis_info133_early = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ @@ -827,8 +823,8 @@ static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - static struct ata_port_info *port_info[2]; - struct ata_port_info *port; + struct ata_port_info port; + const struct ata_port_info *ppi[] = { &port, NULL }; struct pci_dev *host = NULL; struct sis_chipset *chipset = NULL; struct sis_chipset *sets; @@ -968,13 +964,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (chipset == NULL) return -ENODEV; - port = chipset->info; - port->private_data = chipset; + port = *chipset->info; + port.private_data = chipset; sis_fixup(pdev, chipset); - port_info[0] = port_info[1] = port; - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } static const struct pci_device_id sis_pci_tbl[] = { diff --git a/trunk/drivers/ata/pata_sl82c105.c b/trunk/drivers/ata/pata_sl82c105.c index 9aeffdbe2829..f48491ad5f3a 100644 --- a/trunk/drivers/ata/pata_sl82c105.c +++ b/trunk/drivers/ata/pata_sl82c105.c @@ -301,20 +301,22 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev) static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info_dma = { + static const struct ata_port_info info_dma = { .sht = &sl82c105_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &sl82c105_port_ops }; - static struct ata_port_info info_early = { + static const struct ata_port_info info_early = { .sht = &sl82c105_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .port_ops = &sl82c105_port_ops }; - static struct ata_port_info *port_info[2] = { &info_early, &info_early }; + /* for now use only the first port */ + const struct ata_port_info *ppi[] = { &info_early, + &ata_dummy_port_info }; u32 val; int rev; @@ -324,17 +326,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n"); else if (rev <= 5) dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n"); - else { - port_info[0] = &info_dma; - port_info[1] = &info_dma; - } + else + ppi[0] = &info_dma; pci_read_config_dword(dev, 0x40, &val); val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; pci_write_config_dword(dev, 0x40, val); - - return ata_pci_init_one(dev, port_info, 1); /* For now */ + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id sl82c105[] = { diff --git a/trunk/drivers/ata/pata_triflex.c b/trunk/drivers/ata/pata_triflex.c index 349887bf5b93..b1d3076dfe51 100644 --- a/trunk/drivers/ata/pata_triflex.c +++ b/trunk/drivers/ata/pata_triflex.c @@ -194,10 +194,6 @@ static struct scsi_host_template triflex_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations triflex_port_ops = { @@ -237,20 +233,20 @@ static struct ata_port_operations triflex_port_ops = { static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - static struct ata_port_info info = { + static const struct ata_port_info info = { .sht = &triflex_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &triflex_port_ops }; - static struct ata_port_info *port_info[2] = { &info, &info }; + const struct ata_port_info *ppi[] = { &info, NULL }; static int printed_version; if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_init_one(dev, ppi); } static const struct pci_device_id triflex[] = { diff --git a/trunk/drivers/ata/pata_via.c b/trunk/drivers/ata/pata_via.c index 362beb2f489c..e4c71f76bd55 100644 --- a/trunk/drivers/ata/pata_via.c +++ b/trunk/drivers/ata/pata_via.c @@ -301,10 +301,6 @@ static struct scsi_host_template via_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .resume = ata_scsi_device_resume, - .suspend = ata_scsi_device_suspend, -#endif }; static struct ata_port_operations via_port_ops = { @@ -425,7 +421,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags) static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { /* Early VIA without UDMA support */ - static struct ata_port_info via_mwdma_info = { + static const struct ata_port_info via_mwdma_info = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -433,7 +429,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &via_port_ops }; /* Ditto with IRQ masking required */ - static struct ata_port_info via_mwdma_info_borked = { + static const struct ata_port_info via_mwdma_info_borked = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -441,7 +437,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &via_port_ops_noirq, }; /* VIA UDMA 33 devices (and borked 66) */ - static struct ata_port_info via_udma33_info = { + static const struct ata_port_info via_udma33_info = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -450,7 +446,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &via_port_ops }; /* VIA UDMA 66 devices */ - static struct ata_port_info via_udma66_info = { + static const struct ata_port_info via_udma66_info = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -459,7 +455,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &via_port_ops }; /* VIA UDMA 100 devices */ - static struct ata_port_info via_udma100_info = { + static const struct ata_port_info via_udma100_info = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -468,7 +464,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &via_port_ops }; /* UDMA133 with bad AST (All current 133) */ - static struct ata_port_info via_udma133_info = { + static const struct ata_port_info via_udma133_info = { .sht = &via_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING, .pio_mask = 0x1f, @@ -476,7 +472,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = 0x7f, /* FIXME: should check north bridge */ .port_ops = &via_port_ops }; - struct ata_port_info *port_info[2], *type; + struct ata_port_info type; + const struct ata_port_info *ppi[] = { &type, NULL }; struct pci_dev *isa = NULL; const struct via_isa_bridge *config; static int printed_version; @@ -521,25 +518,25 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) switch(config->flags & VIA_UDMA) { case VIA_UDMA_NONE: if (config->flags & VIA_NO_UNMASK) - type = &via_mwdma_info_borked; + type = via_mwdma_info_borked; else - type = &via_mwdma_info; + type = via_mwdma_info; break; case VIA_UDMA_33: - type = &via_udma33_info; + type = via_udma33_info; break; case VIA_UDMA_66: - type = &via_udma66_info; + type = via_udma66_info; /* The 66 MHz devices require we enable the clock */ pci_read_config_dword(pdev, 0x50, &timing); timing |= 0x80008; pci_write_config_dword(pdev, 0x50, timing); break; case VIA_UDMA_100: - type = &via_udma100_info; + type = via_udma100_info; break; case VIA_UDMA_133: - type = &via_udma133_info; + type = via_udma133_info; break; default: WARN_ON(1); @@ -554,10 +551,9 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* We have established the device type, now fire it up */ - type->private_data = (void *)config; + type.private_data = (void *)config; - port_info[0] = port_info[1] = type; - return ata_pci_init_one(pdev, port_info, 2); + return ata_pci_init_one(pdev, ppi); } #ifdef CONFIG_PM diff --git a/trunk/drivers/ata/sata_inic162x.c b/trunk/drivers/ata/sata_inic162x.c index b3b62e985f19..bda5e7747c21 100644 --- a/trunk/drivers/ata/sata_inic162x.c +++ b/trunk/drivers/ata/sata_inic162x.c @@ -135,10 +135,6 @@ static struct scsi_host_template inic_sht = { .slave_configure = inic_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const int scr_map[] = { diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index a097595d4dc7..4cea3ef75226 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -325,10 +325,6 @@ static struct scsi_host_template nv_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static struct scsi_host_template nv_adma_sht = { @@ -347,10 +343,6 @@ static struct scsi_host_template nv_adma_sht = { .slave_configure = nv_adma_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations nv_generic_ops = { @@ -465,7 +457,7 @@ static const struct ata_port_operations nv_adma_ops = { .host_stop = nv_adma_host_stop, }; -static struct ata_port_info nv_port_info[] = { +static const struct ata_port_info nv_port_info[] = { /* generic */ { .sht = &nv_sht, @@ -1545,7 +1537,7 @@ static void nv_adma_error_handler(struct ata_port *ap) static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version = 0; - const struct ata_port_info *ppi[2]; + const struct ata_port_info *ppi[] = { NULL, NULL }; struct ata_host *host; struct nv_host_priv *hpriv; int rc; @@ -1573,8 +1565,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) type = ADMA; } - ppi[0] = ppi[1] = &nv_port_info[type]; - rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + ppi[0] = &nv_port_info[type]; + rc = ata_pci_prepare_native_host(pdev, ppi, &host); if (rc) return rc; diff --git a/trunk/drivers/ata/sata_sil.c b/trunk/drivers/ata/sata_sil.c index 0a1e417f309c..e8483aadd11b 100644 --- a/trunk/drivers/ata/sata_sil.c +++ b/trunk/drivers/ata/sata_sil.c @@ -182,10 +182,6 @@ static struct scsi_host_template sil_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations sil_ops = { diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index b97ee9f31aec..a69d78cd8e9b 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -380,10 +380,6 @@ static struct scsi_host_template sil24_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations sil24_ops = { diff --git a/trunk/drivers/ata/sata_sis.c b/trunk/drivers/ata/sata_sis.c index d8ee062e82fc..ee66c5fa7ac8 100644 --- a/trunk/drivers/ata/sata_sis.c +++ b/trunk/drivers/ata/sata_sis.c @@ -129,7 +129,7 @@ static const struct ata_port_operations sis_ops = { .port_start = ata_port_start, }; -static struct ata_port_info sis_port_info = { +static const struct ata_port_info sis_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, .mwdma_mask = 0x7, @@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; struct ata_port_info pi = sis_port_info; - const struct ata_port_info *ppi[2] = { &pi, &pi }; + const struct ata_port_info *ppi[] = { &pi, NULL }; struct ata_host *host; u32 genctl, val; u8 pmr; @@ -335,7 +335,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) break; } - rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + rc = ata_pci_prepare_native_host(pdev, ppi, &host); if (rc) return rc; diff --git a/trunk/drivers/ata/sata_uli.c b/trunk/drivers/ata/sata_uli.c index f74e383de083..006f5e352658 100644 --- a/trunk/drivers/ata/sata_uli.c +++ b/trunk/drivers/ata/sata_uli.c @@ -125,7 +125,7 @@ static const struct ata_port_operations uli_ops = { .port_start = ata_port_start, }; -static struct ata_port_info uli_port_info = { +static const struct ata_port_info uli_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ @@ -201,19 +201,33 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) n_ports = 2; if (board_idx == uli_5287) n_ports = 4; - rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host); - if (rc) - return rc; + + /* allocate the host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); + if (!host) + return -ENOMEM; hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) return -ENOMEM; host->private_data = hpriv; + /* the first two ports are standard SFF */ + rc = ata_pci_init_native_host(host); + if (rc) + return rc; + + rc = ata_pci_init_bmdma(host); + if (rc) + return rc; + iomap = host->iomap; switch (board_idx) { case uli_5287: + /* If there are four, the last two live right after + * the standard SFF ports. + */ hpriv->scr_cfg_addr[0] = ULI5287_BASE; hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS; diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 939c9246fdd1..d105d2c189d2 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -116,10 +116,6 @@ static struct scsi_host_template svia_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif }; static const struct ata_port_operations vt6420_sata_ops = { @@ -415,7 +411,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) struct ata_host *host; int rc; - rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host); + rc = ata_pci_prepare_native_host(pdev, ppi, &host); if (rc) return rc; *r_host = host; diff --git a/trunk/drivers/ata/sis.h b/trunk/drivers/ata/sis.h index 231da8fc2200..0f2208d8d5ef 100644 --- a/trunk/drivers/ata/sis.h +++ b/trunk/drivers/ata/sis.h @@ -2,4 +2,4 @@ struct ata_port_info; /* pata_sis.c */ -extern struct ata_port_info sis_info133; +extern const struct ata_port_info sis_info133; diff --git a/trunk/drivers/atm/Kconfig b/trunk/drivers/atm/Kconfig index 33687454eb32..f5a47a48c3b4 100644 --- a/trunk/drivers/atm/Kconfig +++ b/trunk/drivers/atm/Kconfig @@ -2,19 +2,22 @@ # ATM device configuration # -menu "ATM drivers" +menuconfig ATM_DRIVERS + bool "ATM drivers" depends on NETDEVICES && ATM + default y + +if ATM_DRIVERS config ATM_DUMMY tristate "Dummy ATM driver" - depends on ATM help Dummy ATM driver. Useful for proxy signalling, testing, and development. If unsure, say N. config ATM_TCP tristate "ATM over TCP" - depends on INET && ATM + depends on INET help ATM over TCP driver. Useful mainly for development and for experiments. If unsure, say N. @@ -30,7 +33,7 @@ config ATM_LANAI config ATM_ENI tristate "Efficient Networks ENI155P" - depends on PCI && ATM + depends on PCI ---help--- Driver for the Efficient Networks ENI155p series and SMC ATM Power155 155 Mbps ATM adapters. Both, the versions with 512KB and @@ -139,7 +142,7 @@ config ATM_ENI_BURST_RX_2W config ATM_FIRESTREAM tristate "Fujitsu FireStream (FS50/FS155) " - depends on PCI && ATM + depends on PCI help Driver for the Fujitsu FireStream 155 (MB86697) and FireStream 50 (MB86695) ATM PCI chips. @@ -149,7 +152,7 @@ config ATM_FIRESTREAM config ATM_ZATM tristate "ZeitNet ZN1221/ZN1225" - depends on PCI && ATM + depends on PCI help Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM adapters. @@ -169,7 +172,7 @@ config ATM_ZATM_DEBUG config ATM_NICSTAR tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" - depends on PCI && ATM && !64BIT + depends on PCI && !64BIT help The NICStAR chipset family is used in a large number of ATM NICs for 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE @@ -202,7 +205,7 @@ config ATM_NICSTAR_USE_IDT77105 config ATM_IDT77252 tristate "IDT 77252 (NICStAR II)" - depends on PCI && ATM + depends on PCI help Driver for the IDT 77252 ATM PCI chips. @@ -237,7 +240,7 @@ config ATM_IDT77252_USE_SUNI config ATM_AMBASSADOR tristate "Madge Ambassador (Collage PCI 155 Server)" - depends on PCI && ATM + depends on PCI select BITREVERSE help This is a driver for ATMizer based ATM card produced by Madge @@ -262,7 +265,7 @@ config ATM_AMBASSADOR_DEBUG config ATM_HORIZON tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)" - depends on PCI && ATM + depends on PCI help This is a driver for the Horizon chipset ATM adapter cards once produced by Madge Networks Ltd. Say Y (or M to compile as a module @@ -286,7 +289,7 @@ config ATM_HORIZON_DEBUG config ATM_IA tristate "Interphase ATM PCI x575/x525/x531" - depends on PCI && ATM && !64BIT + depends on PCI && !64BIT ---help--- This is a driver for the Interphase (i)ChipSAR adapter cards which include a variety of variants in term of the size of the @@ -319,7 +322,7 @@ config ATM_IA_DEBUG config ATM_FORE200E_MAYBE tristate "FORE Systems 200E-series" - depends on (PCI || SBUS) && ATM + depends on PCI || SBUS ---help--- This is a driver for the FORE Systems 200E-series ATM adapter cards. It simultaneously supports PCA-200E and SBA-200E models @@ -436,7 +439,7 @@ config ATM_FORE200E config ATM_HE tristate "ForeRunner HE Series" - depends on PCI && ATM + depends on PCI help This is a driver for the Marconi ForeRunner HE-series ATM adapter cards. It simultaneously supports the 155 and 622 versions. @@ -448,5 +451,4 @@ config ATM_HE_USE_SUNI Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner HE cards. This driver provides carrier detection some statistics. -endmenu - +endif # ATM diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index c9f0f250d78f..801abdd29066 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -268,7 +268,7 @@ static int __devinit aperture_valid(u64 aper, u32 size) printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20); return 0; } - if (aper + size > 0xffffffff) { + if ((u64)aper + size > 0x100000000ULL) { printk(KERN_ERR PFX "Aperture out of bounds\n"); return 0; } diff --git a/trunk/drivers/char/snsc_event.c b/trunk/drivers/char/snsc_event.c index 2f56e8c54897..1b75b0b7d542 100644 --- a/trunk/drivers/char/snsc_event.c +++ b/trunk/drivers/char/snsc_event.c @@ -203,8 +203,6 @@ scdrv_dispatch_event(char *event, int len) class = (code & EV_CLASS_MASK); if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) { - struct task_struct *p; - if (snsc_shutting_down) return; diff --git a/trunk/drivers/media/Kconfig b/trunk/drivers/media/Kconfig index 3a80e0cc7369..624b21cef5b3 100644 --- a/trunk/drivers/media/Kconfig +++ b/trunk/drivers/media/Kconfig @@ -87,6 +87,14 @@ config VIDEO_TVEEPROM tristate depends on I2C +config DAB + boolean "DAB adapters" + default y + ---help--- + Allow selecting support for for Digital Audio Broadcasting (DAB) + Receiver adapters. + +if DAB config USB_DABUSB tristate "DABUSB driver" depends on USB @@ -100,5 +108,6 @@ config USB_DABUSB To compile this driver as a module, choose M here: the module will be called dabusb. +endif # DAB endmenu diff --git a/trunk/drivers/media/Makefile b/trunk/drivers/media/Makefile index c578a529e7a8..8fa19939c2b6 100644 --- a/trunk/drivers/media/Makefile +++ b/trunk/drivers/media/Makefile @@ -5,4 +5,4 @@ obj-y := common/ obj-$(CONFIG_VIDEO_DEV) += video/ obj-$(CONFIG_VIDEO_DEV) += radio/ -obj-$(CONFIG_DVB) += dvb/ +obj-$(CONFIG_DVB_CORE) += dvb/ diff --git a/trunk/drivers/media/common/saa7146_core.c b/trunk/drivers/media/common/saa7146_core.c index 86cbdbcf9d7d..ef3e54cd9407 100644 --- a/trunk/drivers/media/common/saa7146_core.c +++ b/trunk/drivers/media/common/saa7146_core.c @@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa char *mem = vmalloc_32(length); int slen = 0; - if (NULL == mem) { - return NULL; - } + if (NULL == mem) + goto err_null; - if (!(pt->slist = vmalloc_to_sg(mem, pages))) { - vfree(mem); - return NULL; - } + if (!(pt->slist = vmalloc_to_sg(mem, pages))) + goto err_free_mem; - if (saa7146_pgtable_alloc(pci, pt)) { - kfree(pt->slist); - pt->slist = NULL; - vfree(mem); - return NULL; - } + if (saa7146_pgtable_alloc(pci, pt)) + goto err_free_slist; - slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE); - if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) { - return NULL; - } + pt->nents = pages; + slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE); + if (0 == slen) + goto err_free_pgtable; + + if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) + goto err_unmap_sg; return mem; + +err_unmap_sg: + pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); +err_free_pgtable: + saa7146_pgtable_free(pci, pt); +err_free_slist: + kfree(pt->slist); + pt->slist = NULL; +err_free_mem: + vfree(mem); +err_null: + return NULL; +} + +void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt) +{ + pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); + saa7146_pgtable_free(pci, pt); + kfree(pt->slist); + pt->slist = NULL; + vfree(mem); } void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) @@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) return; pci_free_consistent(pci, pt->size, pt->cpu, pt->dma); pt->cpu = NULL; - kfree(pt->slist); - pt->slist = NULL; } int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) @@ -528,6 +543,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc); EXPORT_SYMBOL_GPL(saa7146_pgtable_free); EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single); EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable); +EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable); EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done); EXPORT_SYMBOL_GPL(saa7146_setgpio); diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index c18a5da64934..b4770aecc01d 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -307,7 +307,6 @@ static int fops_release(struct inode *inode, struct file *file) return 0; } -int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg); static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { /* diff --git a/trunk/drivers/media/dvb/Kconfig b/trunk/drivers/media/dvb/Kconfig index a97c8f5e9a5d..efd2b7468158 100644 --- a/trunk/drivers/media/dvb/Kconfig +++ b/trunk/drivers/media/dvb/Kconfig @@ -2,24 +2,16 @@ # Multimedia device configuration # -menu "Digital Video Broadcasting Devices" +source "drivers/media/dvb/dvb-core/Kconfig" -config DVB - bool "DVB For Linux" - depends on NET && INET +menuconfig DVB_CAPTURE_DRIVERS + bool "DVB/ATSC adapters" + depends on DVB_CORE + default y ---help--- - Support Digital Video Broadcasting hardware. Enable this if you - own a DVB adapter and want to use it or if you compile Linux for - a digital SetTopBox. - - API specs and user tools are available from . + Say Y to select Digital TV adapters - Please report problems regarding this driver to the LinuxDVB - mailing list. - - If unsure say N. - -source "drivers/media/dvb/dvb-core/Kconfig" +if DVB_CAPTURE_DRIVERS comment "Supported SAA7146 based PCI Adapters" depends on DVB_CORE && PCI && I2C @@ -48,4 +40,4 @@ comment "Supported DVB Frontends" depends on DVB_CORE source "drivers/media/dvb/frontends/Kconfig" -endmenu +endif # DVB_CAPTURE_DRIVERS diff --git a/trunk/drivers/media/dvb/dvb-core/Kconfig b/trunk/drivers/media/dvb/dvb-core/Kconfig index 1990eda10c46..e3e6839f8073 100644 --- a/trunk/drivers/media/dvb/dvb-core/Kconfig +++ b/trunk/drivers/media/dvb/dvb-core/Kconfig @@ -1,12 +1,22 @@ config DVB_CORE - tristate "DVB Core Support" - depends on DVB + tristate "DVB for Linux" + depends on NET && INET select CRC32 help + Support Digital Video Broadcasting hardware. Enable this if you + own a DVB adapter and want to use it or if you compile Linux for + a digital SetTopBox. + DVB core utility functions for device handling, software fallbacks etc. Say Y when you have a DVB card and want to use it. Say Y if your want to build your drivers outside the kernel, but need the DVB core. All in-kernel drivers will select this automatically if needed. + + API specs and user tools are available from . + + Please report problems regarding this driver to the LinuxDVB + mailing list. + If unsure say N. config DVB_CORE_ATTACH diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 97715f7514d6..403081689de1 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -19,6 +19,7 @@ #define USB_VID_COMPRO_UNK 0x145f #define USB_VID_CYPRESS 0x04b4 #define USB_VID_DIBCOM 0x10b8 +#define USB_VID_DPOSH 0x1498 #define USB_VID_DVICO 0x0fe9 #define USB_VID_EMPIA 0xeb1a #define USB_VID_GENPIX 0x09c0 @@ -61,6 +62,8 @@ #define USB_PID_DIBCOM_STK7700P 0x1e14 #define USB_PID_DIBCOM_STK7700P_PC 0x1e78 #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 +#define USB_PID_DPOSH_M9206_COLD 0x9206 +#define USB_PID_DPOSH_M9206_WARM 0xa090 #define USB_PID_UNIWILL_STK7700P 0x6003 #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 @@ -145,6 +148,8 @@ #define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 #define USB_PID_OPERA1_COLD 0x2830 #define USB_PID_OPERA1_WARM 0x3829 +#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 +#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h index 0d721731a524..6f824a569e14 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -119,7 +119,7 @@ struct usb_data_stream_properties { * @caps: capabilities of the DVB USB device. * @pid_filter_count: number of PID filter position in the optional hardware * PID-filter. - * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the + * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the * device (not URB submitting/killing). * @pid_filter_ctrl: called to en/disable the PID filter, if any. * @pid_filter: called to set/unset a PID for filtering. diff --git a/trunk/drivers/media/dvb/dvb-usb/m920x.c b/trunk/drivers/media/dvb/dvb-usb/m920x.c index 45d7bc214c18..c546ddeda5d4 100644 --- a/trunk/drivers/media/dvb/dvb-usb/m920x.c +++ b/trunk/drivers/media/dvb/dvb-usb/m920x.c @@ -3,8 +3,8 @@ * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org) * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, version 2. * * see Documentation/dvb/README.dvb-usb for more information */ @@ -22,26 +22,7 @@ static int dvb_usb_m920x_debug; module_param_named(debug,dvb_usb_m920x_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); -static struct dvb_usb_rc_key megasky_rc_keys [] = { - { 0x0, 0x12, KEY_POWER }, - { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ - { 0x0, 0x02, KEY_CHANNELUP }, - { 0x0, 0x05, KEY_CHANNELDOWN }, - { 0x0, 0x03, KEY_VOLUMEUP }, - { 0x0, 0x06, KEY_VOLUMEDOWN }, - { 0x0, 0x04, KEY_MUTE }, - { 0x0, 0x07, KEY_OK }, /* TS */ - { 0x0, 0x08, KEY_STOP }, - { 0x0, 0x09, KEY_MENU }, /* swap */ - { 0x0, 0x0a, KEY_REWIND }, - { 0x0, 0x1b, KEY_PAUSE }, - { 0x0, 0x1f, KEY_FASTFORWARD }, - { 0x0, 0x0c, KEY_RECORD }, - { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ - { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ -}; - -static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\ +static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, u16 index, void *data, int size) { int ret; @@ -55,14 +36,14 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\ } if (ret != size) { - deb_rc("m920x_read = no data\n"); + deb("m920x_read = no data\n"); return -EIO; } return 0; } -static inline int m9206_write(struct usb_device *udev, u8 request, +static inline int m920x_write(struct usb_device *udev, u8 request, u16 value, u16 index) { int ret; @@ -74,32 +55,40 @@ static inline int m9206_write(struct usb_device *udev, u8 request, return ret; } -static int m9206_init(struct dvb_usb_device *d) +static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) { int ret = 0; /* Remote controller init. */ if (d->props.rc_query) { - if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0) - return ret; + deb("Initialising remote control\n"); + while (rc_seq->address) { + if ((ret = m920x_write(d->udev, M9206_CORE, + rc_seq->data, + rc_seq->address)) != 0) { + deb("Initialising remote control failed\n"); + return ret; + } - if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0) - return ret; + rc_seq++; + } + + deb("Initialising remote control success\n"); } return ret; } -static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - struct m9206_state *m = d->priv; + struct m920x_state *m = d->priv; int i, ret = 0; u8 rc_state[2]; - if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) + if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) goto unlock; - if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) + if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) goto unlock; for (i = 0; i < d->props.rc_key_map_size; i++) @@ -111,6 +100,14 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) *state = REMOTE_NO_KEY_PRESSED; goto unlock; + case 0x88: /* framing error or "invalid code" */ + case 0x99: + case 0xc0: + case 0xd8: + *state = REMOTE_NO_KEY_PRESSED; + m->rep_count = 0; + goto unlock; + case 0x93: case 0x92: m->rep_count = 0; @@ -118,31 +115,32 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) goto unlock; case 0x91: - /* For comfort. */ + /* prevent immediate auto-repeat */ if (++m->rep_count > 2) *state = REMOTE_KEY_REPEAT; + else + *state = REMOTE_NO_KEY_PRESSED; goto unlock; default: - deb_rc("Unexpected rc response %x\n", rc_state[0]); + deb("Unexpected rc state %02x\n", rc_state[0]); *state = REMOTE_NO_KEY_PRESSED; goto unlock; } } if (rc_state[1] != 0) - deb_rc("Unknown rc key %x\n", rc_state[1]); + deb("Unknown rc key %02x\n", rc_state[1]); *state = REMOTE_NO_KEY_PRESSED; - unlock: + unlock: return ret; } /* I2C */ -static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) +static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i, j; @@ -155,33 +153,40 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], return -EAGAIN; for (i = 0; i < num; i++) { - if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) || - msg[i].len == 0) { - /* For a 0 byte message, I think sending the address to index 0x80|0x40 - * would be the correct thing to do. However, zero byte messages are - * only used for probing, and since we don't know how to get the slave's - * ack, we can't probe. */ + if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) { + /* For a 0 byte message, I think sending the address + * to index 0x80|0x40 would be the correct thing to + * do. However, zero byte messages are only used for + * probing, and since we don't know how to get the + * slave's ack, we can't probe. */ ret = -ENOTSUPP; goto unlock; } /* Send START & address/RW bit */ if (!(msg[i].flags & I2C_M_NOSTART)) { - if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0) + if ((ret = m920x_write(d->udev, M9206_I2C, + (msg[i].addr << 1) | + (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0) goto unlock; /* Should check for ack here, if we knew how. */ } if (msg[i].flags & I2C_M_RD) { for (j = 0; j < msg[i].len; j++) { - /* Last byte of transaction? Send STOP, otherwise send ACK. */ - int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01; - if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0) + /* Last byte of transaction? + * Send STOP, otherwise send ACK. */ + int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01; + + if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, + 0x20 | stop, + &msg[i].buf[j], 1)) != 0) goto unlock; } } else { for (j = 0; j < msg[i].len; j++) { /* Last byte of transaction? Then send STOP. */ - int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00; - if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0) + int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00; + + if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0) goto unlock; /* Should check for ack here too. */ } @@ -189,25 +194,25 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], } ret = num; -unlock: + unlock: mutex_unlock(&d->i2c_mutex); return ret; } -static u32 m9206_i2c_func(struct i2c_adapter *adapter) +static u32 m920x_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; } -static struct i2c_algorithm m9206_i2c_algo = { - .master_xfer = m9206_i2c_xfer, - .functionality = m9206_i2c_func, +static struct i2c_algorithm m920x_i2c_algo = { + .master_xfer = m920x_i2c_xfer, + .functionality = m920x_i2c_func, }; - -static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, - int pid) +/* pid filter */ +static int m920x_set_filter(struct dvb_usb_adapter *adap, + int type, int idx, int pid) { int ret = 0; @@ -216,18 +221,18 @@ static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx, pid |= 0x8000; - if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) + if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) return ret; - if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) + if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) return ret; return ret; } -static int m9206_update_filters(struct dvb_usb_adapter *adap) +static int m920x_update_filters(struct dvb_usb_adapter *adap) { - struct m9206_state *m = adap->dev->priv; + struct m920x_state *m = adap->dev->priv; int enabled = m->filtering_enabled; int i, ret = 0, filter = 0; @@ -236,14 +241,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap) enabled = 0; /* Disable all filters */ - if ((ret = m9206_set_filter(adap, 0x81, 1, enabled)) != 0) + if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0) return ret; for (i = 0; i < M9206_MAX_FILTERS; i++) - if ((ret = m9206_set_filter(adap, 0x81, i + 2, 0)) != 0) + if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0) return ret; - if ((ret = m9206_set_filter(adap, 0x82, 0, 0x0)) != 0) + if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0) return ret; /* Set */ @@ -252,40 +257,38 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap) if (m->filters[i] == 0) continue; - if ((ret = m9206_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) + if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) return ret; filter++; } } - if ((ret = m9206_set_filter(adap, 0x82, 0, 0x02f5)) != 0) + if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0) return ret; return ret; } -static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) +static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - struct m9206_state *m = adap->dev->priv; + struct m920x_state *m = adap->dev->priv; m->filtering_enabled = onoff ? 1 : 0; - return m9206_update_filters(adap); + return m920x_update_filters(adap); } -static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) +static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) { - struct m9206_state *m = adap->dev->priv; + struct m920x_state *m = adap->dev->priv; m->filters[index] = onoff ? pid : 0; - return m9206_update_filters(adap); + return m920x_update_filters(adap); } -static int m9206_firmware_download(struct usb_device *udev, - const struct firmware *fw) +static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw) { u16 value, index, size; u8 read[4], *buff; @@ -293,13 +296,13 @@ static int m9206_firmware_download(struct usb_device *udev, buff = kmalloc(65536, GFP_KERNEL); - if ((ret = m9206_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) + if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) goto done; - deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]); + deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]); - if ((ret = m9206_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0) + if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0) goto done; - deb_rc("%x\n", read[0]); + deb("%x\n", read[0]); for (pass = 0; pass < 2; pass++) { for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { @@ -317,11 +320,11 @@ static int m9206_firmware_download(struct usb_device *udev, memcpy(buff, fw->data + i, size); ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), - M9206_FW, - USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, buff, size, 20); + M9206_FW, + USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, buff, size, 20); if (ret != size) { - deb_rc("error while uploading fw!\n"); + deb("error while uploading fw!\n"); ret = -EIO; goto done; } @@ -330,7 +333,7 @@ static int m9206_firmware_download(struct usb_device *udev, i += size; } if (i != fw->size) { - deb_rc("bad firmware file!\n"); + deb("bad firmware file!\n"); ret = -EINVAL; goto done; } @@ -338,11 +341,11 @@ static int m9206_firmware_download(struct usb_device *udev, msleep(36); - /* m9206 will disconnect itself from the bus after this. */ - (void) m9206_write(udev, M9206_CORE, 0x01, M9206_FW_GO); - deb_rc("firmware uploaded!\n"); + /* m920x will disconnect itself from the bus after this. */ + (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO); + deb("firmware uploaded!\n"); - done: + done: kfree(buff); return ret; @@ -362,7 +365,8 @@ static int m920x_identify_state(struct usb_device *udev, return 0; } -static int megasky_mt352_demod_init(struct dvb_frontend *fe) +/* demod configurations */ +static int m920x_mt352_demod_init(struct dvb_frontend *fe) { u8 config[] = { CONFIG, 0x3d }; u8 clock[] = { CLOCK_CTL, 0x30 }; @@ -382,74 +386,174 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) mt352_write(fe, unk1, ARRAY_SIZE(unk1)); mt352_write(fe, unk2, ARRAY_SIZE(unk2)); - deb_rc("Demod init!\n"); + deb("Demod init!\n"); return 0; } -static struct mt352_config megasky_mt352_config = { +static struct mt352_config m920x_mt352_config = { .demod_address = 0x0f, .no_tuner = 1, - .demod_init = megasky_mt352_demod_init, + .demod_init = m920x_mt352_demod_init, +}; + +static struct tda1004x_config m920x_tda10046_08_config = { + .demod_address = 0x08, + .invert = 0, + .invert_oclk = 0, + .ts_mode = TDA10046_TS_SERIAL, + .xtal_freq = TDA10046_XTAL_16M, + .if_freq = TDA10046_FREQ_045, + .agc_config = TDA10046_AGC_TDA827X, + .gpio_config = TDA10046_GPTRI, + .request_firmware = NULL, +}; + +static struct tda1004x_config m920x_tda10046_0b_config = { + .demod_address = 0x0b, + .invert = 0, + .invert_oclk = 0, + .ts_mode = TDA10046_TS_SERIAL, + .xtal_freq = TDA10046_XTAL_16M, + .if_freq = TDA10046_FREQ_045, + .agc_config = TDA10046_AGC_TDA827X, + .gpio_config = TDA10046_GPTRI, + .request_firmware = NULL, /* uses firmware EEPROM */ +}; + +/* tuner configurations */ +static struct qt1010_config m920x_qt1010_config = { + .i2c_address = 0x62 }; -static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) +/* Callbacks for DVB USB */ +static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap) { - deb_rc("megasky_frontend_attach!\n"); + deb("%s\n",__FUNCTION__); - if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) + if ((adap->fe = dvb_attach(mt352_attach, + &m920x_mt352_config, + &adap->dev->i2c_adap)) == NULL) return -EIO; return 0; } -static struct qt1010_config megasky_qt1010_config = { - .i2c_address = 0x62 -}; - -static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) +static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap) { - if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, - &megasky_qt1010_config) == NULL) - return -ENODEV; + deb("%s\n",__FUNCTION__); + + if ((adap->fe = dvb_attach(tda10046_attach, + &m920x_tda10046_08_config, + &adap->dev->i2c_adap)) == NULL) + return -EIO; return 0; } -static struct tda1004x_config digivox_tda10046_config = { - .demod_address = 0x08, - .invert = 0, - .invert_oclk = 0, - .ts_mode = TDA10046_TS_SERIAL, - .xtal_freq = TDA10046_XTAL_16M, - .if_freq = TDA10046_FREQ_045, - .agc_config = TDA10046_AGC_TDA827X, - .gpio_config = TDA10046_GPTRI, - .request_firmware = NULL, -}; - -static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap) +static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap) { - deb_rc("digivox_tda10046_frontend_attach!\n"); + deb("%s\n",__FUNCTION__); - if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config, + if ((adap->fe = dvb_attach(tda10046_attach, + &m920x_tda10046_0b_config, &adap->dev->i2c_adap)) == NULL) return -EIO; return 0; } -static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap) +static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { - if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, - NULL) == NULL) + deb("%s\n",__FUNCTION__); + + if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL) return -ENODEV; + return 0; } +static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap) +{ + deb("%s\n",__FUNCTION__); + + if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL) + return -ENODEV; + + return 0; +} + +static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap) +{ + deb("%s\n",__FUNCTION__); + + if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) + return -ENODEV; + + return 0; +} + +/* device-specific initialization */ +static struct m920x_inits megasky_rc_init [] = { + { M9206_RC_INIT2, 0xa8 }, + { M9206_RC_INIT1, 0x51 }, + { } /* terminating entry */ +}; + +static struct m920x_inits tvwalkertwin_rc_init [] = { + { M9206_RC_INIT2, 0x00 }, + { M9206_RC_INIT1, 0xef }, + { 0xff28, 0x00 }, + { 0xff23, 0x00 }, + { 0xff21, 0x30 }, + { } /* terminating entry */ +}; + +/* ir keymaps */ +static struct dvb_usb_rc_key megasky_rc_keys [] = { + { 0x0, 0x12, KEY_POWER }, + { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ + { 0x0, 0x02, KEY_CHANNELUP }, + { 0x0, 0x05, KEY_CHANNELDOWN }, + { 0x0, 0x03, KEY_VOLUMEUP }, + { 0x0, 0x06, KEY_VOLUMEDOWN }, + { 0x0, 0x04, KEY_MUTE }, + { 0x0, 0x07, KEY_OK }, /* TS */ + { 0x0, 0x08, KEY_STOP }, + { 0x0, 0x09, KEY_MENU }, /* swap */ + { 0x0, 0x0a, KEY_REWIND }, + { 0x0, 0x1b, KEY_PAUSE }, + { 0x0, 0x1f, KEY_FASTFORWARD }, + { 0x0, 0x0c, KEY_RECORD }, + { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ + { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ +}; + +static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { + { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */ + { 0x0, 0x02, KEY_CAMERA }, /* snapshot */ + { 0x0, 0x03, KEY_MUTE }, + { 0x0, 0x04, KEY_REWIND }, + { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */ + { 0x0, 0x06, KEY_FASTFORWARD }, + { 0x0, 0x07, KEY_RECORD }, + { 0x0, 0x08, KEY_STOP }, + { 0x0, 0x09, KEY_TIME }, /* Timeshift */ + { 0x0, 0x0c, KEY_COFFEE }, /* Recall */ + { 0x0, 0x0e, KEY_CHANNELUP }, + { 0x0, 0x12, KEY_POWER }, + { 0x0, 0x15, KEY_MENU }, /* source */ + { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */ + { 0x0, 0x1a, KEY_CHANNELDOWN }, + { 0x0, 0x1b, KEY_VOLUMEDOWN }, + { 0x0, 0x1e, KEY_VOLUMEUP }, +}; + /* DVB USB Driver stuff */ static struct dvb_usb_device_properties megasky_properties; static struct dvb_usb_device_properties digivox_mini_ii_properties; +static struct dvb_usb_device_properties tvwalkertwin_properties; +static struct dvb_usb_device_properties dposh_properties; static int m920x_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -457,19 +561,57 @@ static int m920x_probe(struct usb_interface *intf, struct dvb_usb_device *d; struct usb_host_interface *alt; int ret; + struct m920x_inits *rc_init_seq = NULL; + int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; - deb_rc("Probed!\n"); + deb("Probing for m920x device at interface %d\n", bInterfaceNumber); - if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) || - ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0)) - goto found; + if (bInterfaceNumber == 0) { + /* Single-tuner device, or first interface on + * multi-tuner device + */ - return ret; + if ((ret = dvb_usb_device_init(intf, &megasky_properties, + THIS_MODULE, &d)) == 0) { + rc_init_seq = megasky_rc_init; + goto found; + } + + if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, + THIS_MODULE, &d)) == 0) { + /* No remote control, so no rc_init_seq */ + goto found; + } + + /* This configures both tuners on the TV Walker Twin */ + if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties, + THIS_MODULE, &d)) == 0) { + rc_init_seq = tvwalkertwin_rc_init; + goto found; + } + + if ((ret = dvb_usb_device_init(intf, &dposh_properties, + THIS_MODULE, &d)) == 0) { + /* Remote controller not supported yet. */ + goto found; + } + + return ret; + } else { + /* Another interface on a multi-tuner device */ -found: + /* The LifeView TV Walker Twin gets here, but struct + * tvwalkertwin_properties already configured both + * tuners, so there is nothing for us to do here + */ + + return -ENODEV; + } + + found: alt = usb_altnum_to_altsetting(intf, 1); if (alt == NULL) { - deb_rc("No alt found!\n"); + deb("No alt found!\n"); return -ENODEV; } @@ -478,7 +620,7 @@ static int m920x_probe(struct usb_interface *intf, if (ret < 0) return ret; - if ((ret = m9206_init(d)) != 0) + if ((ret = m920x_init(d, rc_init_seq)) != 0) return ret; return ret; @@ -488,6 +630,12 @@ static struct usb_device_id m920x_table [] = { { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, USB_PID_MSI_DIGI_VOX_MINI_II) }, + { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, + USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) }, + { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, + USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) }, + { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) }, + { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, m920x_table); @@ -497,14 +645,14 @@ static struct dvb_usb_device_properties megasky_properties = { .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-megasky-02.fw", - .download_firmware = m9206_firmware_download, + .download_firmware = m920x_firmware_download, .rc_interval = 100, .rc_key_map = megasky_rc_keys, .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), - .rc_query = m9206_rc_query, + .rc_query = m920x_rc_query, - .size_of_priv = sizeof(struct m9206_state), + .size_of_priv = sizeof(struct m920x_state), .identify_state = m920x_identify_state, .num_adapters = 1, @@ -513,11 +661,11 @@ static struct dvb_usb_device_properties megasky_properties = { DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 8, - .pid_filter = m9206_pid_filter, - .pid_filter_ctrl = m9206_pid_filter_ctrl, + .pid_filter = m920x_pid_filter, + .pid_filter_ctrl = m920x_pid_filter_ctrl, - .frontend_attach = megasky_mt352_frontend_attach, - .tuner_attach = megasky_qt1010_tuner_attach, + .frontend_attach = m920x_mt352_frontend_attach, + .tuner_attach = m920x_qt1010_tuner_attach, .stream = { .type = USB_BULK, @@ -530,7 +678,7 @@ static struct dvb_usb_device_properties megasky_properties = { } }, }}, - .i2c_algo = &m9206_i2c_algo, + .i2c_algo = &m920x_i2c_algo, .num_device_descs = 1, .devices = { @@ -546,22 +694,22 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { .usb_ctrl = DEVICE_SPECIFIC, .firmware = "dvb-usb-digivox-02.fw", - .download_firmware = m9206_firmware_download, + .download_firmware = m920x_firmware_download, - .size_of_priv = sizeof(struct m9206_state), + .size_of_priv = sizeof(struct m920x_state), .identify_state = m920x_identify_state, .num_adapters = 1, .adapter = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 8, - .pid_filter = m9206_pid_filter, - .pid_filter_ctrl = m9206_pid_filter_ctrl, + .pid_filter = m920x_pid_filter, + .pid_filter_ctrl = m920x_pid_filter_ctrl, - .frontend_attach = digivox_tda10046_frontend_attach, - .tuner_attach = digivox_tda8275_tuner_attach, + .frontend_attach = m920x_tda10046_08_frontend_attach, + .tuner_attach = m920x_tda8275_60_tuner_attach, .stream = { .type = USB_BULK, @@ -574,7 +722,7 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { } }, }}, - .i2c_algo = &m9206_i2c_algo, + .i2c_algo = &m920x_i2c_algo, .num_device_descs = 1, .devices = { @@ -585,6 +733,122 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { } }; +/* LifeView TV Walker Twin support by Nick Andrew + * + * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A + * TDA10046 #0 is located at i2c address 0x08 + * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working) + * TDA8275A #0 is located at i2c address 0x60 + * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working) + */ +static struct dvb_usb_device_properties tvwalkertwin_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-tvwalkert.fw", + .download_firmware = m920x_firmware_download, + + .rc_interval = 100, + .rc_key_map = tvwalkertwin_rc_keys, + .rc_key_map_size = ARRAY_SIZE(tvwalkertwin_rc_keys), + .rc_query = m920x_rc_query, + + .size_of_priv = sizeof(struct m920x_state), + + .identify_state = m920x_identify_state, + .num_adapters = 1, + .adapter = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + + .pid_filter_count = 8, + .pid_filter = m920x_pid_filter, + .pid_filter_ctrl = m920x_pid_filter_ctrl, + + .frontend_attach = m920x_tda10046_08_frontend_attach, + .tuner_attach = m920x_tda8275_60_tuner_attach, + + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }},{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + + .pid_filter_count = 8, + .pid_filter = m920x_pid_filter, + .pid_filter_ctrl = m920x_pid_filter_ctrl, + + .frontend_attach = m920x_tda10046_0b_frontend_attach, + .tuner_attach = m920x_tda8275_61_tuner_attach, + + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + }}, + .i2c_algo = &m920x_i2c_algo, + + .num_device_descs = 1, + .devices = { + { .name = "LifeView TV Walker Twin DVB-T USB2.0", + .cold_ids = { &m920x_table[2], NULL }, + .warm_ids = { &m920x_table[3], NULL }, + }, + } +}; + +static struct dvb_usb_device_properties dposh_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-dposh-01.fw", + .download_firmware = m920x_firmware_download, + + .size_of_priv = sizeof(struct m920x_state), + + .identify_state = m920x_identify_state, + .num_adapters = 1, + .adapter = {{ + /* Hardware pid filters don't work with this device/firmware */ + + .frontend_attach = m920x_mt352_frontend_attach, + .tuner_attach = m920x_qt1010_tuner_attach, + + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x81, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + }}, + .i2c_algo = &m920x_i2c_algo, + + .num_device_descs = 1, + .devices = { + { .name = "Dposh DVB-T USB2.0", + .cold_ids = { &m920x_table[4], NULL }, + .warm_ids = { &m920x_table[5], NULL }, + }, + } +}; + static struct usb_driver m920x_driver = { .name = "dvb_usb_m920x", .probe = m920x_probe, @@ -615,6 +879,11 @@ module_init (m920x_module_init); module_exit (m920x_module_exit); MODULE_AUTHOR("Aapo Tahkola "); -MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / Uli m920x"); +MODULE_DESCRIPTION("DVB Driver for ULI M920x"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); + +/* + * Local variables: + * c-basic-offset: 8 + */ diff --git a/trunk/drivers/media/dvb/dvb-usb/m920x.h b/trunk/drivers/media/dvb/dvb-usb/m920x.h index 7dd3db65c80e..2c8942d04222 100644 --- a/trunk/drivers/media/dvb/dvb-usb/m920x.h +++ b/trunk/drivers/media/dvb/dvb-usb/m920x.h @@ -4,7 +4,7 @@ #define DVB_USB_LOG_PREFIX "m920x" #include "dvb-usb.h" -#define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args) +#define deb(args...) dprintk(dvb_usb_m920x_debug,0x01,args) #define M9206_CORE 0x22 #define M9206_RC_STATE 0xff51 @@ -59,9 +59,18 @@ What any other bits might mean, or how to get the slave's ACK/NACK response to a write, is unknown. */ -struct m9206_state { +struct m920x_state { u16 filters[M9206_MAX_FILTERS]; int filtering_enabled; int rep_count; }; + +/* Initialisation data for the m920x + */ + +struct m920x_inits { + u16 address; + u8 data; +}; + #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c index 3ecb2e0ce80f..c3fdc7cd094e 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe, static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *m) { - //struct vp702x_fe_state *st = fe->demodulator_priv; - u8 cmd[8];//,ibuf[10]; + struct vp702x_fe_state *st = fe->demodulator_priv; + u8 cmd[8],ibuf[10]; memset(cmd,0,8); deb_fe("%s\n",__FUNCTION__); @@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, memcpy(&cmd[3], m->msg, m->msg_len); cmd[7] = vp702x_chksum(cmd,0,7); -// vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); + vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); -// if (ibuf[2] == 0 && ibuf[3] == 0) -// deb_fe("diseqc cmd failed.\n"); -// else -// deb_fe("diseqc cmd succeeded.\n"); + if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("diseqc cmd failed.\n"); + else + deb_fe("diseqc cmd succeeded.\n"); return 0; } diff --git a/trunk/drivers/media/dvb/pluto2/pluto2.c b/trunk/drivers/media/dvb/pluto2/pluto2.c index 058df5c10034..08a2599ed74a 100644 --- a/trunk/drivers/media/dvb/pluto2/pluto2.c +++ b/trunk/drivers/media/dvb/pluto2/pluto2.c @@ -293,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) * but no packets have been transfered. * [2] Sometimes (actually very often) NBPACKETS stays at zero * although one packet has been transfered. + * [3] Sometimes (actually rarely), the card gets into an erroneous + * mode where it continuously generates interrupts, claiming it + * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet + * has been transfered. Only a reset seems to solve this */ if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { unsigned int i = 0; while (pluto->dma_buf[i] == 0x47) i += 188; nbpackets = i / 188; + if (i == 0) { + pluto_reset_ts(pluto, 1); + dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n"); + } } dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 67becdd4db60..ef1108c0bf11 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data) if (!budget->feeding1 || (newdma == olddma)) return; + /* Ensure streamed PCI data is synced to CPU */ + pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); + #if 0 /* track rps1 activity */ printk("vpeirq: %02x Event Counter 1 0x%04x\n", @@ -2679,8 +2682,8 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, err_pci_free_5: pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus); err_saa71466_vfree_4: - if (!av7110->grabbing) - saa7146_pgtable_free(pdev, &av7110->pt); + if (av7110->grabbing) + saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt); err_i2c_del_3: i2c_del_adapter(&av7110->i2c_adap); err_dvb_unregister_adapter_2: @@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa) SAA7146_ISR_CLEAR(saa, MASK_10); msleep(50); tasklet_kill(&av7110->vpe_tasklet); - saa7146_pgtable_free(saa->pci, &av7110->pt); + saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt); } av7110_exit_v4l(av7110); diff --git a/trunk/drivers/media/dvb/ttpci/budget-ci.c b/trunk/drivers/media/dvb/ttpci/budget-ci.c index 4ed4599ce816..9d42f88ebb0e 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-ci.c +++ b/trunk/drivers/media/dvb/ttpci/budget-ci.c @@ -904,7 +904,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc band = 1; } else if (tuner_frequency < 200000000) { cp = 6; - band = 2; + band = 1; } else if (tuner_frequency < 290000000) { cp = 3; band = 2; diff --git a/trunk/drivers/media/dvb/ttpci/budget-core.c b/trunk/drivers/media/dvb/ttpci/budget-core.c index 6b97dc1e6b65..2557ac9620d0 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-core.c +++ b/trunk/drivers/media/dvb/ttpci/budget-core.c @@ -195,6 +195,9 @@ static void vpeirq(unsigned long data) u32 newdma = saa7146_read(budget->dev, PCI_VDP3); u32 count; + /* Ensure streamed PCI data is synced to CPU */ + pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); + /* nearest lower position divisible by 188 */ newdma -= newdma % 188; @@ -504,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, strcpy(budget->i2c_adap.name, budget->card->name); if (i2c_add_adapter(&budget->i2c_adap) < 0) { - dvb_unregister_adapter(&budget->dvb_adapter); - return -ENOMEM; + ret = -ENOMEM; + goto err_dvb_unregister; } ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); - if (NULL == - (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) { + budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt); + if (NULL == budget->grabbing) { ret = -ENOMEM; - goto err; + goto err_del_i2c; } saa7146_write(dev, PCI_BT_V1, 0x001c0000); @@ -526,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - if (budget_register(budget) == 0) { - return 0; - } -err: - i2c_del_adapter(&budget->i2c_adap); + if (budget_register(budget) == 0) + return 0; /* Everything OK */ + + /* An error occurred, cleanup resources */ + saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - vfree(budget->grabbing); +err_del_i2c: + i2c_del_adapter(&budget->i2c_adap); +err_dvb_unregister: dvb_unregister_adapter(&budget->dvb_adapter); return ret; @@ -555,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget) budget_unregister(budget); - i2c_del_adapter(&budget->i2c_adap); - - dvb_unregister_adapter(&budget->dvb_adapter); - tasklet_kill(&budget->vpe_tasklet); - saa7146_pgtable_free(dev->pci, &budget->pt); + saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - vfree(budget->grabbing); + i2c_del_adapter(&budget->i2c_adap); + + dvb_unregister_adapter(&budget->dvb_adapter); return 0; } diff --git a/trunk/drivers/media/radio/Kconfig b/trunk/drivers/media/radio/Kconfig index af66a5d5ecd8..a6ac82a609d4 100644 --- a/trunk/drivers/media/radio/Kconfig +++ b/trunk/drivers/media/radio/Kconfig @@ -2,8 +2,14 @@ # Multimedia Video device configuration # -menu "Radio Adapters" +menuconfig RADIO_ADAPTERS + bool "Radio Adapters" depends on VIDEO_DEV + default y + ---help--- + Say Y here to enable selecting AM/FM radio adapters. + +if RADIO_ADAPTERS config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" @@ -328,4 +334,5 @@ config USB_DSBR To compile this driver as a module, choose M here: the module will be called dsbr100. -endmenu + +endif # RADIO_ADAPTERS diff --git a/trunk/drivers/media/radio/dsbr100.c b/trunk/drivers/media/radio/dsbr100.c index 449df1bb00d3..3bd07f7e3774 100644 --- a/trunk/drivers/media/radio/dsbr100.c +++ b/trunk/drivers/media/radio/dsbr100.c @@ -33,6 +33,10 @@ History: + Version 0.42: + Converted dsbr100 to use video_ioctl2 + by Douglas Landgraf + Version 0.41-ac1: Alan Cox: Some cleanups and fixes @@ -121,8 +125,6 @@ devices, that would be 76 and 91. */ static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id); static void usb_dsbr100_disconnect(struct usb_interface *intf); -static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); static int usb_dsbr100_open(struct inode *inode, struct file *file); static int usb_dsbr100_close(struct inode *inode, struct file *file); @@ -142,26 +144,6 @@ struct dsbr100_device { }; -/* File system interface */ -static const struct file_operations usb_dsbr100_fops = { - .owner = THIS_MODULE, - .open = usb_dsbr100_open, - .release = usb_dsbr100_close, - .ioctl = usb_dsbr100_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, -}; - -/* V4L interface */ -static struct video_device dsbr100_videodev_template= -{ - .owner = THIS_MODULE, - .name = "D-Link DSB-R 100", - .type = VID_TYPE_TUNER, - .fops = &usb_dsbr100_fops, - .release = video_device_release, -}; - static struct usb_device_id usb_dsbr100_device_table [] = { { USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) }, { } /* Terminating entry */ @@ -252,37 +234,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio) /* USB subsystem interface begins here */ -/* check if the device is present and register with v4l and -usb if it is */ -static int usb_dsbr100_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dsbr100_device *radio; - - if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) - return -ENOMEM; - if (!(radio->videodev = video_device_alloc())) { - kfree(radio); - return -ENOMEM; - } - memcpy(radio->videodev, &dsbr100_videodev_template, - sizeof(dsbr100_videodev_template)); - radio->removed = 0; - radio->users = 0; - radio->usbdev = interface_to_usbdev(intf); - radio->curfreq = FREQ_MIN*FREQ_MUL; - video_set_drvdata(radio->videodev, radio); - if (video_register_device(radio->videodev, VFL_TYPE_RADIO, - radio_nr)) { - warn("Could not register video device"); - video_device_release(radio->videodev); - kfree(radio); - return -EIO; - } - usb_set_intfdata(intf, radio); - return 0; -} - /* handle unplugging of the device, release data structures if nothing keeps us from doing it. If something is still keeping us busy, the release callback of v4l will take care @@ -307,133 +258,147 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) } -/* Video for Linux interface */ +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *v) +{ + strlcpy(v->driver, "dsbr100", sizeof(v->driver)); + strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card)); + sprintf(v->bus_info, "ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; +} -static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) { - struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); + + if (v->index > 0) + return -EINVAL; + + dsbr100_getstat(radio); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + v->rangelow = FREQ_MIN*FREQ_MUL; + v->rangehigh = FREQ_MAX*FREQ_MUL; + v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability = V4L2_TUNER_CAP_LOW; + if(radio->stereo) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal = 0xffff; /* We can't get the signal strength */ + return 0; +} - if (!radio) - return -EIO; +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + if (v->index > 0) + return -EINVAL; - switch(cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *v = arg; - memset(v,0,sizeof(*v)); - strlcpy(v->driver, "dsbr100", sizeof (v->driver)); - strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card)); - sprintf(v->bus_info,"ISA"); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER; + return 0; +} - return 0; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *v = arg; +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); - if (v->index > 0) - return -EINVAL; + radio->curfreq = f->frequency; + if (dsbr100_setfreq(radio, radio->curfreq)==-1) + warn("Set frequency failed"); + return 0; +} - dsbr100_getstat(radio); +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); - memset(v,0,sizeof(*v)); - strcpy(v->name, "FM"); - v->type = V4L2_TUNER_RADIO; + f->type = V4L2_TUNER_RADIO; + f->frequency = radio->curfreq; + return 0; +} - v->rangelow = FREQ_MIN*FREQ_MUL; - v->rangehigh = FREQ_MAX*FREQ_MUL; - v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; - v->capability=V4L2_TUNER_CAP_LOW; - if(radio->stereo) - v->audmode = V4L2_TUNER_MODE_STEREO; - else - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xFFFF; /* We can't get the signal strength */ +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); return 0; } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *v = arg; - - if (v->index > 0) - return -EINVAL; + } + return -EINVAL; +} - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); - radio->curfreq = f->frequency; - if (dsbr100_setfreq(radio, radio->curfreq)==-1) - warn("Set frequency failed"); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value = radio->muted; + return 0; + } + return -EINVAL; +} - f->type = V4L2_TUNER_RADIO; - f->frequency = radio->curfreq; +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct dsbr100_device *radio = video_get_drvdata(video_devdata(file)); - return 0; - } - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { - if (qc->id && qc->id == radio_qctrl[i].id) { - memcpy(qc, &(radio_qctrl[i]), - sizeof(*qc)); - return 0; - } - } - return -EINVAL; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value=radio->muted; - return 0; - } - return -EINVAL; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl= arg; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) { - if (dsbr100_stop(radio)==-1) - warn("Radio did not respond properly"); - } else { - if (dsbr100_start(radio)==-1) - warn("Radio did not respond properly"); - } - return 0; - } - return -EINVAL; + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + if (dsbr100_stop(radio)==-1) + warn("Radio did not respond properly"); + } else { + if (dsbr100_start(radio)==-1) + warn("Radio did not respond properly"); } - default: - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - usb_dsbr100_do_ioctl); + return 0; } + return -EINVAL; } -static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) { - return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl); + if (a->index > 1) + return -EINVAL; + + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + return 0; +} + +static int vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index != 0) + return -EINVAL; + return 0; } static int usb_dsbr100_open(struct inode *inode, struct file *file) @@ -465,6 +430,68 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file) return 0; } +/* File system interface */ +static const struct file_operations usb_dsbr100_fops = { + .owner = THIS_MODULE, + .open = usb_dsbr100_open, + .release = usb_dsbr100_close, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .llseek = no_llseek, +}; + +/* V4L2 interface */ +static struct video_device dsbr100_videodev_template = +{ + .owner = THIS_MODULE, + .name = "D-Link DSB-R 100", + .type = VID_TYPE_TUNER, + .fops = &usb_dsbr100_fops, + .release = video_device_release, + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, +}; + +/* check if the device is present and register with v4l and +usb if it is */ +static int usb_dsbr100_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct dsbr100_device *radio; + + if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) + return -ENOMEM; + if (!(radio->videodev = video_device_alloc())) { + kfree(radio); + return -ENOMEM; + } + memcpy(radio->videodev, &dsbr100_videodev_template, + sizeof(dsbr100_videodev_template)); + radio->removed = 0; + radio->users = 0; + radio->usbdev = interface_to_usbdev(intf); + radio->curfreq = FREQ_MIN*FREQ_MUL; + video_set_drvdata(radio->videodev, radio); + if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) { + warn("Could not register video device"); + video_device_release(radio->videodev); + kfree(radio); + return -EIO; + } + usb_set_intfdata(intf, radio); + return 0; +} + static int __init dsbr100_init(void) { int retval = usb_register(&usb_dsbr100_driver); diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index 8fbf0d8bd278..8cf2e9df5c8a 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -48,6 +48,25 @@ #define CADET_VERSION KERNEL_VERSION(0,3,3) +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .name = "Volume", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + static int io=-1; /* default to isapnp activation */ static int radio_nr = -1; static int users=0; @@ -347,135 +366,165 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) } +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *v) +{ + v->capabilities = + V4L2_CAP_TUNER | + V4L2_CAP_READWRITE; + v->version = CADET_VERSION; + strcpy(v->driver, "ADS Cadet"); + strcpy(v->card, "ADS Cadet"); + return 0; +} -static int cadet_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) { - switch(cmd) - { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - memset(cap,0,sizeof(*cap)); - cap->capabilities = - V4L2_CAP_TUNER | - V4L2_CAP_READWRITE; - cap->version = CADET_VERSION; - strcpy(cap->driver, "ADS Cadet"); - strcpy(cap->card, "ADS Cadet"); - return 0; + v->type = V4L2_TUNER_RADIO; + switch (v->index) { + case 0: + strcpy(v->name, "FM"); + v->capability = V4L2_TUNER_CAP_STEREO; + v->rangelow = 1400; /* 87.5 MHz */ + v->rangehigh = 1728; /* 108.0 MHz */ + v->rxsubchans=cadet_getstereo(); + switch (v->rxsubchans){ + case V4L2_TUNER_SUB_MONO: + v->audmode = V4L2_TUNER_MODE_MONO; + break; + case V4L2_TUNER_SUB_STEREO: + v->audmode = V4L2_TUNER_MODE_STEREO; + break; + default: ; } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - memset(t,0,sizeof(*t)); - t->type = V4L2_TUNER_RADIO; - switch (t->index) - { - case 0: strcpy(t->name, "FM"); - t->capability = V4L2_TUNER_CAP_STEREO; - t->rangelow = 1400; /* 87.5 MHz */ - t->rangehigh = 1728; /* 108.0 MHz */ - t->rxsubchans=cadet_getstereo(); - switch (t->rxsubchans){ - case V4L2_TUNER_SUB_MONO: - t->audmode = V4L2_TUNER_MODE_MONO; - break; - case V4L2_TUNER_SUB_STEREO: - t->audmode = V4L2_TUNER_MODE_STEREO; - break; - default: ; - } - break; - case 1: strcpy(t->name, "AM"); - t->capability = V4L2_TUNER_CAP_LOW; - t->rangelow = 8320; /* 520 kHz */ - t->rangehigh = 26400; /* 1650 kHz */ - t->rxsubchans = V4L2_TUNER_SUB_MONO; - t->audmode = V4L2_TUNER_MODE_MONO; - break; - default: - return -EINVAL; - } + break; + case 1: + strcpy(v->name, "AM"); + v->capability = V4L2_TUNER_CAP_LOW; + v->rangelow = 8320; /* 520 kHz */ + v->rangehigh = 26400; /* 1650 kHz */ + v->rxsubchans = V4L2_TUNER_SUB_MONO; + v->audmode = V4L2_TUNER_MODE_MONO; + break; + default: + return -EINVAL; + } + v->signal = sigstrength; /* We might need to modify scaling of this */ + return 0; +} - t->signal = sigstrength; /* We might need to modify scaling of this */ - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; - if((t->index != 0)&&(t->index != 1)) - return -EINVAL; +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *v) +{ + if((v->index != 0)&&(v->index != 1)) + return -EINVAL; + curtuner = v->index; + return 0; +} - curtuner = t->index; - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; - memset(f,0,sizeof(*f)); - f->tuner = curtuner; - f->type = V4L2_TUNER_RADIO; - f->frequency = cadet_getfreq(); - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - if (f->type != V4L2_TUNER_RADIO){ - return -EINVAL; - } - if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) { - return -EINVAL; - } - if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) { - return -EINVAL; - } - cadet_setfreq(f->frequency); - return 0; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *c = arg; - switch (c->id){ - case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ - c->value = (cadet_getvol() == 0); - break; - case V4L2_CID_AUDIO_VOLUME: - c->value = cadet_getvol(); - break; - default: - return -EINVAL; - } - return 0; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *c = arg; - switch (c->id){ - case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ - if (c->value) cadet_setvol(0); - else cadet_setvol(0xffff); - break; - case V4L2_CID_AUDIO_VOLUME: - cadet_setvol(c->value); - break; - default: - return -EINVAL; - } +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + f->tuner = curtuner; + f->type = V4L2_TUNER_RADIO; + f->frequency = cadet_getfreq(); + return 0; +} + + +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + if (f->type != V4L2_TUNER_RADIO) + return -EINVAL; + if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) + return -EINVAL; + if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) + return -EINVAL; + cadet_setfreq(f->frequency); + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); return 0; } + } + return -EINVAL; +} - default: - return -ENOIOCTLCMD; +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + switch (ctrl->id){ + case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ + ctrl->value = (cadet_getvol() == 0); + break; + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = cadet_getvol(); + break; + default: + return -EINVAL; } + return 0; } -static int -cadet_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) { - return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl); + switch (ctrl->id){ + case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ + if (ctrl->value) + cadet_setvol(0); + else + cadet_setvol(0xffff); + break; + case V4L2_CID_AUDIO_VOLUME: + cadet_setvol(ctrl->value); + break; + default: + return -EINVAL; + } + return 0; +} + +static int vidioc_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index > 1) + return -EINVAL; + strcpy(a->name, "Radio"); + a->capability = V4L2_AUDCAP_STEREO; + return 0; +} + +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; + return 0; +} + +static int vidioc_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + if (a->index != 0) + return -EINVAL; + return 0; } static int @@ -512,7 +561,7 @@ static const struct file_operations cadet_fops = { .open = cadet_open, .release = cadet_release, .read = cadet_read, - .ioctl = cadet_ioctl, + .ioctl = video_ioctl2, .poll = cadet_poll, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, @@ -524,6 +573,18 @@ static struct video_device cadet_radio= .name = "Cadet radio", .type = VID_TYPE_TUNER, .fops = &cadet_fops, + .vidioc_querycap = vidioc_querycap, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_g_audio = vidioc_g_audio, + .vidioc_s_audio = vidioc_s_audio, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, }; static struct pnp_device_id cadet_pnp_devices[] = { diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c index 11f80cacd6ed..8e33a19a22a3 100644 --- a/trunk/drivers/media/radio/radio-maestro.c +++ b/trunk/drivers/media/radio/radio-maestro.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -110,7 +109,6 @@ struct radio_device { muted, /* VIDEO_AUDIO_MUTE */ stereo, /* VIDEO_TUNER_STEREO_ON */ tuned; /* signal strength (0 or 0xffff) */ - struct mutex lock; }; static u32 radio_bits_get(struct radio_device *dev) @@ -394,7 +392,6 @@ static int __devinit maestro_probe(struct pci_dev *pdev, } radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA; - mutex_init(&radio_unit->lock); maestro_radio_inst = video_device_alloc(); if (maestro_radio_inst == NULL) { diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c index a4715901512d..203f4373eeb8 100644 --- a/trunk/drivers/media/radio/radio-zoltrix.c +++ b/trunk/drivers/media/radio/radio-zoltrix.c @@ -410,7 +410,6 @@ static struct video_device zoltrix_radio = .owner = THIS_MODULE, .name = "Zoltrix Radio Plus", .type = VID_TYPE_TUNER, - .hardware = 0, .fops = &zoltrix_fops, .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index bc773781993a..5cb3f54b548b 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -2,14 +2,19 @@ # Multimedia Video device configuration # -menu "Video Capture Adapters" +menuconfig VIDEO_CAPTURE_DRIVERS + bool "Video capture adapters" depends on VIDEO_DEV + default y + ---help--- + Say Y here to enable selecting the video adapters for + webcams, analog TV, and hybrid analog/digital TV. + Some of those devices also supports FM radio. -comment "Video Capture Adapters" +if VIDEO_CAPTURE_DRIVERS config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" - depends on VIDEO_DEV default n ---help--- Say Y here to enable advanced debugging functionality on some @@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO # menu "Encoders/decoders and other helper chips" - depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO + depends on !VIDEO_HELPER_CHIPS_AUTO comment "Audio decoders" @@ -61,7 +66,7 @@ config VIDEO_TDA7432 config VIDEO_TDA9840 tristate "Philips TDA9840 audio processor" - depends on VIDEO_DEV && I2C + depends on I2C ---help--- Support for tda9840 audio decoder chip found on some Zoran boards. @@ -79,7 +84,7 @@ config VIDEO_TDA9875 config VIDEO_TEA6415C tristate "Philips TEA6415C audio processor" - depends on VIDEO_DEV && I2C + depends on I2C ---help--- Support for tea6415c audio decoder chip found on some bt8xx boards. @@ -88,7 +93,7 @@ config VIDEO_TEA6415C config VIDEO_TEA6420 tristate "Philips TEA6420 audio processor" - depends on VIDEO_DEV && I2C + depends on I2C ---help--- Support for tea6420 audio decoder chip found on some bt8xx boards. @@ -469,7 +474,7 @@ config VIDEO_SAA5246A config VIDEO_SAA5249 tristate "SAA5249 Teletext processor" - depends on VIDEO_DEV && I2C && VIDEO_V4L2 + depends on I2C && VIDEO_V4L2 help Support for I2C bus based teletext using the SAA5249 chip. At the moment this is only useful on some European WinTV cards. @@ -479,7 +484,7 @@ config VIDEO_SAA5249 config TUNER_3036 tristate "SAB3036 tuner" - depends on VIDEO_DEV && I2C && VIDEO_V4L1 + depends on I2C && VIDEO_V4L1 help Say Y here to include support for Philips SAB3036 compatible tuners. If in doubt, say N. @@ -681,8 +686,12 @@ config VIDEO_CAFE_CCIC # USB Multimedia device configuration # -menu "V4L USB devices" - depends on USB && VIDEO_DEV +menuconfig V4L_USB_DRIVERS + bool "V4L USB devices" + depends on USB + default y + +if V4L_USB_DRIVERS source "drivers/media/video/pvrusb2/Kconfig" @@ -707,7 +716,7 @@ config VIDEO_OVCAMCHIP config USB_W9968CF tristate "USB W996[87]CF JPEG Dual Mode Camera support" - depends on USB && VIDEO_V4L1 && I2C + depends on VIDEO_V4L1 && I2C select VIDEO_OVCAMCHIP ---help--- Say Y here if you want support for cameras based on OV681 or @@ -725,7 +734,7 @@ config USB_W9968CF config USB_OV511 tristate "USB OV511 Camera support" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. See @@ -736,7 +745,7 @@ config USB_OV511 config USB_SE401 tristate "USB SE401 Camera support" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. See @@ -749,7 +758,7 @@ source "drivers/media/video/sn9c102/Kconfig" config USB_STV680 tristate "USB STV680 (Pencam) Camera support" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. This includes the Pencam line of cameras. @@ -765,7 +774,7 @@ source "drivers/media/video/pwc/Kconfig" config USB_ZR364XX tristate "USB ZR364XX Camera support" - depends on USB && VIDEO_V4L2 + depends on VIDEO_V4L2 ---help--- Say Y here if you want to connect this type of camera to your computer's USB port. @@ -775,6 +784,6 @@ config USB_ZR364XX To compile this driver as a module, choose M here: the module will be called zr364xx. -endmenu # V4L USB devices +endif # V4L_USB_DRIVERS -endmenu +endif # VIDEO_CAPTURE_DRIVERS diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index 1757a588970f..67bda9f9a44b 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -555,7 +555,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) { struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; - int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC); + int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60); switch (fmt->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -567,7 +567,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; - Vlines = pix->height + (is_pal ? 4 : 7); + Vlines = pix->height + (is_50Hz ? 4 : 7); if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index 2ebde2fdbcbe..543b05ebc0e7 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "cx88.h" @@ -612,7 +613,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board } /* Driver asked for hardware access. */ -int cx8802_request_acquire(struct cx8802_driver *drv) +static int cx8802_request_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; @@ -632,7 +633,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv) } /* Driver asked to release hardware. */ -int cx8802_request_release(struct cx8802_driver *drv) +static int cx8802_request_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index b94ef8ab28c1..98fa35421bdd 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "cx88.h" diff --git a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c index 6068c9bf82cd..82bc3a28aa22 100644 --- a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c @@ -111,10 +111,6 @@ static struct i2c_adapter vp3054_i2c_adap_template = { .id = I2C_HW_B_CX2388x, }; -static struct i2c_client vp3054_i2c_client_template = { - .name = "VP-3054", -}; - int vp3054_i2c_probe(struct cx8802_dev *dev) { struct cx88_core *core = dev->core; @@ -133,8 +129,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) sizeof(vp3054_i2c->adap)); memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, sizeof(vp3054_i2c->algo)); - memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template, - sizeof(vp3054_i2c->client)); vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL; @@ -144,7 +138,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) vp3054_i2c->algo.data = dev; i2c_set_adapdata(&vp3054_i2c->adap, dev); vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; - vp3054_i2c->client.adapter = &vp3054_i2c->adap; vp3054_bit_setscl(dev,1); vp3054_bit_setsda(dev,1); diff --git a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h index b7a0a04d2423..637a7d232238 100644 --- a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h +++ b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h @@ -26,7 +26,6 @@ struct vp3054_i2c_state { struct i2c_adapter adap; struct i2c_algo_bit_data algo; - struct i2c_client client; u32 state; }; diff --git a/trunk/drivers/media/video/em28xx/Kconfig b/trunk/drivers/media/video/em28xx/Kconfig index 9285a58e47aa..3823b62da4a4 100644 --- a/trunk/drivers/media/video/em28xx/Kconfig +++ b/trunk/drivers/media/video/em28xx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && USB && I2C + depends on VIDEO_V4L1 && I2C select VIDEO_BUF select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/trunk/drivers/media/video/et61x251/Kconfig b/trunk/drivers/media/video/et61x251/Kconfig index c6bff705688d..664676f44068 100644 --- a/trunk/drivers/media/video/et61x251/Kconfig +++ b/trunk/drivers/media/video/et61x251/Kconfig @@ -1,6 +1,6 @@ config USB_ET61X251 tristate "USB ET61X[12]51 PC Camera Controller support" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y here if you want support for cameras based on Etoms ET61X151 or ET61X251 PC Camera Controllers. diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.c b/trunk/drivers/media/video/ivtv/ivtv-driver.c index 45b9328a538f..e29f949adf57 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.c +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.c @@ -74,7 +74,7 @@ int ivtv_first_minor = 0; struct ivtv *ivtv_cards[IVTV_MAX_CARDS]; /* Protects ivtv_cards_active */ -spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(ivtv_cards_lock); /* add your revision and whatnot here */ static struct pci_device_id ivtv_pci_tbl[] __devinitdata = { diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index 1637097ddec7..8976487a65f3 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) struct ivtv_open_id *item; struct ivtv *itv = NULL; struct ivtv_stream *s = NULL; - int minor = MINOR(inode->i_rdev); + int minor = iminor(inode); /* Find which card this open was on */ spin_lock(&ivtv_cards_lock); diff --git a/trunk/drivers/media/video/pvrusb2/Kconfig b/trunk/drivers/media/video/pvrusb2/Kconfig index 5645c9318890..d0c2cd785430 100644 --- a/trunk/drivers/media/video/pvrusb2/Kconfig +++ b/trunk/drivers/media/video/pvrusb2/Kconfig @@ -1,6 +1,6 @@ config VIDEO_PVRUSB2 tristate "Hauppauge WinTV-PVR USB2 support" - depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL + depends on VIDEO_V4L2 && I2C && EXPERIMENTAL select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 5669c8ca9ca3..20b614436d2c 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -391,22 +391,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw) int pvr2_encoder_configure(struct pvr2_hdw *hdw) { int ret; + int val; pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" " (cx2341x module)"); hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; hdw->enc_ctl_state.width = hdw->res_hor_val; hdw->enc_ctl_state.height = hdw->res_ver_val; - hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & - (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? + hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ? 0 : 1); ret = 0; ret |= pvr2_encoder_prep_config(hdw); + /* saa7115: 0xf0 */ + val = 0xf0; + if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { + /* ivtv cx25840: 0x140 */ + val = 0x140; + } + if (!ret) ret = pvr2_encoder_vcmd( hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, - 0xf0, 0xf0); + val, val); /* setup firmware to notify us about some events (don't know why...) */ if (!ret) ret = pvr2_encoder_vcmd( diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c index acf651e01f94..1311891e7ee3 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -83,7 +83,7 @@ static struct pvr2_string_table pvr2_client_lists[] = { }; static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; -static DECLARE_MUTEX(pvr2_unit_sem); +static DEFINE_MUTEX(pvr2_unit_mtx); static int ctlchg = 0; static int initusbreset = 1; @@ -2076,14 +2076,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); if (!hdw->ctl_read_urb) goto fail; - down(&pvr2_unit_sem); do { + mutex_lock(&pvr2_unit_mtx); do { for (idx = 0; idx < PVR_NUM; idx++) { if (unit_pointers[idx]) continue; hdw->unit_number = idx; unit_pointers[idx] = hdw; break; } - } while (0); up(&pvr2_unit_sem); + } while (0); mutex_unlock(&pvr2_unit_mtx); cnt1 = 0; cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); @@ -2186,13 +2186,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) } pvr2_i2c_core_done(hdw); pvr2_hdw_remove_usb_stuff(hdw); - down(&pvr2_unit_sem); do { + mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && (hdw->unit_number < PVR_NUM) && (unit_pointers[hdw->unit_number] == hdw)) { unit_pointers[hdw->unit_number] = NULL; } - } while (0); up(&pvr2_unit_sem); + } while (0); mutex_unlock(&pvr2_unit_mtx); kfree(hdw->controls); kfree(hdw->mpeg_ctrl_info); kfree(hdw->std_defs); diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 58fc3c730fe1..6786d3c0c98b 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -23,6 +23,7 @@ #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" #include "pvrusb2-fx2-cmd.h" +#include "pvrusb2.h" #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) @@ -38,6 +39,10 @@ static unsigned int i2c_scan = 0; module_param(i2c_scan, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); +static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 }; +module_param_array(ir_mode, int, NULL, 0444); +MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); + static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, unsigned int detail, char *buf,unsigned int maxlen); @@ -273,6 +278,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw, return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); } +/* This is an entry point designed to always fail any attempt to perform a + transfer. We use this to cause certain I2C addresses to not be + probed. */ +static int i2c_black_hole(struct pvr2_hdw *hdw, + u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) +{ + return -EIO; +} + /* This is a special entry point that is entered if an I2C operation is attempted to a cx25840 chip on model 24xxx hardware. This chip can sometimes wedge itself. Worse still, when this happens msp3400 can @@ -994,10 +1008,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) } /* However, deal with various special cases for 24xxx hardware. */ + if (ir_mode[hdw->unit_number] == 0) { + printk(KERN_INFO "%s: IR disabled\n",hdw->name); + hdw->i2c_func[0x18] = i2c_black_hole; + } else if (ir_mode[hdw->unit_number] == 1) { + if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { + hdw->i2c_func[0x18] = i2c_24xxx_ir; + } + } if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { hdw->i2c_func[0x1b] = i2c_hack_wm8775; hdw->i2c_func[0x44] = i2c_hack_cx25840; - hdw->i2c_func[0x18] = i2c_24xxx_ir; } // Configure the adapter and set up everything else related to it. diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index a741c556a39a..7ab79baa1c8c 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -518,40 +518,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) } sfp->item_last = cip; - cip->attr_name.attr.owner = THIS_MODULE; cip->attr_name.attr.name = "name"; cip->attr_name.attr.mode = S_IRUGO; cip->attr_name.show = fp->show_name; - cip->attr_type.attr.owner = THIS_MODULE; cip->attr_type.attr.name = "type"; cip->attr_type.attr.mode = S_IRUGO; cip->attr_type.show = fp->show_type; - cip->attr_min.attr.owner = THIS_MODULE; cip->attr_min.attr.name = "min_val"; cip->attr_min.attr.mode = S_IRUGO; cip->attr_min.show = fp->show_min; - cip->attr_max.attr.owner = THIS_MODULE; cip->attr_max.attr.name = "max_val"; cip->attr_max.attr.mode = S_IRUGO; cip->attr_max.show = fp->show_max; - cip->attr_val.attr.owner = THIS_MODULE; cip->attr_val.attr.name = "cur_val"; cip->attr_val.attr.mode = S_IRUGO; - cip->attr_custom.attr.owner = THIS_MODULE; cip->attr_custom.attr.name = "custom_val"; cip->attr_custom.attr.mode = S_IRUGO; - cip->attr_enum.attr.owner = THIS_MODULE; cip->attr_enum.attr.name = "enum_val"; cip->attr_enum.attr.mode = S_IRUGO; cip->attr_enum.show = fp->show_enum; - cip->attr_bits.attr.owner = THIS_MODULE; cip->attr_bits.attr.name = "bit_val"; cip->attr_bits.attr.mode = S_IRUGO; cip->attr_bits.show = fp->show_bits; @@ -616,12 +608,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) dip = kzalloc(sizeof(*dip),GFP_KERNEL); if (!dip) return; - dip->attr_debugcmd.attr.owner = THIS_MODULE; dip->attr_debugcmd.attr.name = "debugcmd"; dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; dip->attr_debugcmd.show = debugcmd_show; dip->attr_debugcmd.store = debugcmd_store; - dip->attr_debuginfo.attr.owner = THIS_MODULE; dip->attr_debuginfo.attr.name = "debuginfo"; dip->attr_debuginfo.attr.mode = S_IRUGO; dip->attr_debuginfo.show = debuginfo_show; @@ -811,7 +801,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, return; } - sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; sfp->attr_v4l_minor_number.show = v4l_minor_number_show; @@ -825,7 +814,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->v4l_minor_number_created_ok = !0; } - sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE; sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number"; sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO; sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show; @@ -839,7 +827,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->v4l_radio_minor_number_created_ok = !0; } - sfp->attr_unit_number.attr.owner = THIS_MODULE; sfp->attr_unit_number.attr.name = "unit_number"; sfp->attr_unit_number.attr.mode = S_IRUGO; sfp->attr_unit_number.show = unit_number_show; @@ -852,7 +839,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp, sfp->unit_number_created_ok = !0; } - sfp->attr_bus_info.attr.owner = THIS_MODULE; sfp->attr_bus_info.attr.name = "bus_info_str"; sfp->attr_bus_info.attr.mode = S_IRUGO; sfp->attr_bus_info.show = bus_info_show; diff --git a/trunk/drivers/media/video/pwc/Kconfig b/trunk/drivers/media/video/pwc/Kconfig index 8fdf7101d3bf..7298cf2e1650 100644 --- a/trunk/drivers/media/video/pwc/Kconfig +++ b/trunk/drivers/media/video/pwc/Kconfig @@ -1,6 +1,6 @@ config USB_PWC tristate "USB Philips Cameras" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y or M here if you want to use one of these Philips & OEM webcams: diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 4ea479baee74..50f15adfa7c8 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -1170,6 +1170,42 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE2, }, }, + [SAA7134_BOARD_ECS_TVP3XP_4CB6] = { + /* Barry Scott */ + .name = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)", + .audio_clock = 0x187de7, + .tuner_type = TUNER_PHILIPS_PAL_I, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_tv_mono, + .vmux = 1, + .amux = LINE2, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = "CVid over SVid", + .vmux = 0, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, [SAA7134_BOARD_AVACSSMARTTV] = { /* Roman Pszonczenko */ .name = "AVACS SmartTV", @@ -2754,6 +2790,35 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE1, }, }, + [SAA7134_BOARD_KWORLD_DVBT_210] = { + .name = "KWorld DVB-T 210", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 1 << 21, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, + }, [SAA7134_BOARD_KWORLD_ATSC110] = { .name = "Kworld ATSC110", .audio_clock = 0x00187de7, @@ -3407,6 +3472,36 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x0200000, }, }, + [SAA7134_BOARD_SABRENT_TV_PCB05] = { + .name = "Sabrent PCMCIA TV-PCB05", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_comp2, + .vmux = 0, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .mute = { + .name = name_mute, + .amux = TV, + }, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -3515,7 +3610,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5168, /* Animation Technologies (LifeView) */ - .subdevice = 0x0214, /* Standard PCI, LR214WF */ + .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */ + .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5168, /* Animation Technologies (LifeView) */ + .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, },{ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -3687,6 +3788,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1019, .subdevice = 0x4cb5, .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x1019, + .subdevice = 0x4cb6, + .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -3913,6 +4020,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x17de, .subdevice = 0x7201, .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x17de, + .subdevice = 0x7250, + .driver_data = SAA7134_BOARD_KWORLD_DVBT_210, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */ @@ -4099,6 +4212,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1043, .subdevice = 0x4857, .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */ + .subdevice = 0x2003, /* OEM cardbus */ + .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05, },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -4178,6 +4297,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_CINERGY600_MK3: case SAA7134_BOARD_ECS_TVP3XP: case SAA7134_BOARD_ECS_TVP3XP_4CB5: + case SAA7134_BOARD_ECS_TVP3XP_4CB6: case SAA7134_BOARD_MD2819: case SAA7134_BOARD_KWORLD_VSTREAM_XPERT: case SAA7134_BOARD_KWORLD_XPERT: @@ -4426,6 +4546,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) } break; case SAA7134_BOARD_PINNACLE_PCTV_310i: + case SAA7134_BOARD_KWORLD_DVBT_210: case SAA7134_BOARD_TEVION_DVBT_220RF: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 65aec881bbde..e0eec80088c7 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -887,6 +887,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = { .antenna_switch= 2, .request_firmware = philips_tda1004x_request_firmware }; +static struct tda1004x_config kworld_dvb_t_210_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X, + .gpio_config = TDA10046_GP11_I, + .if_freq = TDA10046_FREQ_045, + .i2c_gate = 0x4b, + .tuner_address = 0x61, + .tuner_config = 2, + .antenna_switch= 1, + .request_firmware = philips_tda1004x_request_firmware +}; /* ------------------------------------------------------------------ * special case: this card uses saa713x GPIO22 for the mode switch */ @@ -1039,6 +1053,9 @@ static int dvb_init(struct saa7134_dev *dev) dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; } break; + case SAA7134_BOARD_KWORLD_DVBT_210: + configure_tda827x_fe(dev, &kworld_dvb_t_210_config); + break; case SAA7134_BOARD_PHILIPS_TIGER: configure_tda827x_fe(dev, &philips_tiger_config); break; diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index 62224cc958f1..15623b27ad2e 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -235,6 +235,9 @@ struct saa7134_format { #define SAA7134_BOARD_AVERMEDIA_M102 110 #define SAA7134_BOARD_ASUS_P7131_4871 111 #define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112 +#define SAA7134_BOARD_ECS_TVP3XP_4CB6 113 +#define SAA7134_BOARD_KWORLD_DVBT_210 114 +#define SAA7134_BOARD_SABRENT_TV_PCB05 115 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/trunk/drivers/media/video/sn9c102/Kconfig b/trunk/drivers/media/video/sn9c102/Kconfig index 19204f5686e1..f71f272776de 100644 --- a/trunk/drivers/media/video/sn9c102/Kconfig +++ b/trunk/drivers/media/video/sn9c102/Kconfig @@ -1,6 +1,6 @@ config USB_SN9C102 tristate "USB SN9C1xx PC Camera Controller support" - depends on USB && VIDEO_V4L2 + depends on VIDEO_V4L2 ---help--- Say Y here if you want support for cameras based on SONiX SN9C101, SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers. diff --git a/trunk/drivers/media/video/sn9c102/sn9c102.h b/trunk/drivers/media/video/sn9c102/sn9c102.h index 680e74634527..11fcb49f5b99 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102.h @@ -141,7 +141,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id) void sn9c102_attach_sensor(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) + const struct sn9c102_sensor* sensor) { memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); } diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_core.c b/trunk/drivers/media/video/sn9c102/sn9c102_core.c index 89f83354de3b..74a204f8ebc8 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_core.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_core.c @@ -48,8 +48,8 @@ #define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia" #define SN9C102_AUTHOR_EMAIL "" #define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.39" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 39) +#define SN9C102_MODULE_VERSION "1:1.44" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 44) /*****************************************************************************/ @@ -209,38 +209,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) } /*****************************************************************************/ + /* - * Write a sequence of count value/register pairs. Returns -1 after the - * first failed write, or 0 for no errors. - */ + Write a sequence of count value/register pairs. Returns -1 after the first + failed write, or 0 for no errors. +*/ int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2], int count) { struct usb_device* udev = cam->usbdev; - u8* value = cam->control_buffer; /* Needed for DMA'able memory */ + u8* buff = cam->control_buffer; int i, res; for (i = 0; i < count; i++) { u8 index = valreg[i][1]; /* - * index is a u8, so it must be <256 and can't be out of range. - * If we put in a check anyway, gcc annoys us with a warning - * that our check is useless. People get all uppity when they - * see warnings in the kernel compile. - */ - - *value = valreg[i][0]; - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x08, 0x41, index, 0, - value, 1, SN9C102_CTRL_TIMEOUT); + index is a u8, so it must be <256 and can't be out of range. + If we put in a check anyway, gcc annoys us with a warning + hat our check is useless. People get all uppity when they + see warnings in the kernel compile. + */ + + *buff = valreg[i][0]; + + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, + 0x41, index, 0, buff, 1, + SN9C102_CTRL_TIMEOUT); + if (res < 0) { DBG(3, "Failed to write a register (value 0x%02X, " - "index 0x%02X, error %d)", *value, index, res); + "index 0x%02X, error %d)", *buff, index, res); return -1; } - cam->reg[index] = *value; + cam->reg[index] = *buff; } return 0; @@ -272,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) } -/* NOTE: reading some registers always returns 0 */ -static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) +/* NOTE: with the SN9C10[123] reading some registers always returns 0 */ +int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) { struct usb_device* udev = cam->usbdev; u8* buff = cam->control_buffer; @@ -299,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) static int -sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) +sn9c102_i2c_wait(struct sn9c102_device* cam, + const struct sn9c102_sensor* sensor) { int i, r; @@ -320,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) static int sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) + const struct sn9c102_sensor* sensor) { int r , err = 0; @@ -342,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, static int sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor) + const struct sn9c102_sensor* sensor) { int r; r = sn9c102_read_reg(cam, 0x08); @@ -352,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 data0, u8 data1, - u8 n, u8 buffer[]) + const struct sn9c102_sensor* sensor, u8 data0, + u8 data1, u8 n, u8 buffer[]) { struct usb_device* udev = cam->usbdev; u8* data = cam->control_buffer; - int err = 0, res; + int i = 0, err = 0, res; /* Write cycle */ data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) | @@ -402,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, } if (buffer) - memcpy(buffer, data, sizeof(buffer)); + for (i = 0; i < n && i < 5; i++) + buffer[n-i-1] = data[4-i]; return (int)data[4]; } @@ -410,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 n, u8 data0, + const struct sn9c102_sensor* sensor, u8 n, u8 data0, u8 data1, u8 data2, u8 data3, u8 data4, u8 data5) { struct usb_device* udev = cam->usbdev; @@ -449,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, int sn9c102_i2c_try_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 address) + const struct sn9c102_sensor* sensor, u8 address) { return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id, address, 1, NULL); @@ -458,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam, int sn9c102_i2c_try_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 address, u8 value) + const struct sn9c102_sensor* sensor, u8 address, u8 value) { return sn9c102_i2c_try_raw_write(cam, sensor, 3, sensor->i2c_slave_id, address, @@ -657,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) } -static void -sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f) -{ - static const u8 eoi_marker[2] = {0xff, 0xd9}; - - memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker)); - f->buf.bytesused += sizeof(eoi_marker); -} - - static void sn9c102_urb_complete(struct urb *urb) { struct sn9c102_device* cam = urb->context; @@ -3181,14 +3176,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, static const struct file_operations sn9c102_fops = { .owner = THIS_MODULE, - .open = sn9c102_open, + .open = sn9c102_open, .release = sn9c102_release, - .ioctl = sn9c102_ioctl, + .ioctl = sn9c102_ioctl, .compat_ioctl = v4l_compat_ioctl32, - .read = sn9c102_read, - .poll = sn9c102_poll, - .mmap = sn9c102_mmap, - .llseek = no_llseek, + .read = sn9c102_read, + .poll = sn9c102_poll, + .mmap = sn9c102_mmap, + .llseek = no_llseek, }; /*****************************************************************************/ @@ -3251,7 +3246,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) break; } - for (i = 0; sn9c102_sensor_table[i]; i++) { + for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) { err = sn9c102_sensor_table[i](cam); if (!err) break; @@ -3262,7 +3257,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) DBG(3, "Support for %s maintained by %s", cam->sensor.name, cam->sensor.maintainer); } else { - DBG(1, "No supported image sensor detected"); + DBG(1, "No supported image sensor detected for this bridge"); err = -ENODEV; goto fail; } diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h index f49bd8c5b86e..916054faf9be 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -86,6 +86,8 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, /* SN9C105 */ + { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), }, + { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, @@ -100,6 +102,7 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, /* SN9C120 */ + { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), }, { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, @@ -148,7 +151,6 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */ &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ - NULL, }; #endif /* _SN9C102_DEVTABLE_H_ */ diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c index 28a861aed044..eaf9ad0dc8a6 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131d.c @@ -144,7 +144,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor hv7131d = { +static const struct sn9c102_sensor hv7131d = { .name = "HV7131D", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, @@ -248,12 +248,10 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam) err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, {0x28, 0x17}); - if (err) - return -EIO; r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00); r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01); - if (r0 < 0 || r1 < 0) + if (err || r0 < 0 || r1 < 0) return -EIO; if (r0 != 0x00 || r1 != 0x04) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c index 5a495baa5f95..0fc401223cfc 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_hv7131r.c @@ -44,7 +44,6 @@ static int hv7131r_init(struct sn9c102_device* cam) {0xb0, 0x2b}, {0xc0, 0x2c}, {0xd0, 0x2d}, {0xe0, 0x2e}, {0xf0, 0x2f}, {0xff, 0x30}); - break; case BRIDGE_SN9C105: case BRIDGE_SN9C120: @@ -254,7 +253,7 @@ static int hv7131r_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor hv7131r = { +static const struct sn9c102_sensor hv7131r = { .name = "HV7131R", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120, @@ -350,11 +349,8 @@ int sn9c102_probe_hv7131r(struct sn9c102_device* cam) {0x34, 0x01}, {0x20, 0x17}, {0x34, 0x01}, {0x46, 0x01}); - if (err) - return -EIO; - devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00); - if (devid < 0) + if (err || devid < 0) return -EIO; if (devid != 0x02) diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c b/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c index 9200845d011b..00b134ca0a3d 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_mi0343.c @@ -55,45 +55,45 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, struct v4l2_control* ctrl) { struct sn9c102_sensor* s = sn9c102_get_sensor(cam); - u8 data[5+1]; + u8 data[2]; switch (ctrl->id) { case V4L2_CID_EXPOSURE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2, + data) < 0) return -EIO; - ctrl->value = data[2]; + ctrl->value = data[0]; return 0; case V4L2_CID_GAIN: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2, + data) < 0) return -EIO; break; case V4L2_CID_HFLIP: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2, + data) < 0) return -EIO; - ctrl->value = data[3] & 0x20 ? 1 : 0; + ctrl->value = data[1] & 0x20 ? 1 : 0; return 0; case V4L2_CID_VFLIP: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2, + data) < 0) return -EIO; - ctrl->value = data[3] & 0x80 ? 1 : 0; + ctrl->value = data[1] & 0x80 ? 1 : 0; return 0; case V4L2_CID_RED_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2, + data) < 0) return -EIO; break; case V4L2_CID_BLUE_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2, + data) < 0) return -EIO; break; case SN9C102_V4L2_CID_GREEN_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2, + data) < 0) return -EIO; break; default: @@ -105,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, case V4L2_CID_RED_BALANCE: case V4L2_CID_BLUE_BALANCE: case SN9C102_V4L2_CID_GREEN_BALANCE: - ctrl->value = data[3] | (data[2] << 8); + ctrl->value = data[1] | (data[0] << 8); if (ctrl->value >= 0x10 && ctrl->value <= 0x3f) ctrl->value -= 0x10; else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f) @@ -223,7 +223,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor mi0343 = { +static const struct sn9c102_sensor mi0343 = { .name = "MI-0343", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, @@ -332,20 +332,17 @@ static struct sn9c102_sensor mi0343 = { int sn9c102_probe_mi0343(struct sn9c102_device* cam) { - u8 data[5+1]; - int err = 0; - - err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, - {0x28, 0x17}); + u8 data[2]; - if (err) + if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, + {0x28, 0x17})) return -EIO; if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00, 2, data) < 0) return -EIO; - if (data[4] != 0x32 || data[3] != 0xe3) + if (data[1] != 0x42 || data[0] != 0xe3) return -ENODEV; sn9c102_attach_sensor(cam, &mi0343); diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c b/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c index 64698acb0b15..f8d81d82e8d5 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_mi0360.c @@ -27,20 +27,105 @@ static int mi0360_init(struct sn9c102_device* cam) struct sn9c102_sensor* s = sn9c102_get_sensor(cam); int err = 0; - err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, - {0x0a, 0x14}, {0x40, 0x01}, - {0x20, 0x17}, {0x07, 0x18}, - {0xa0, 0x19}, {0x02, 0x1c}, - {0x03, 0x1d}, {0x0f, 0x1e}, - {0x0c, 0x1f}, {0x00, 0x20}, - {0x10, 0x21}, {0x20, 0x22}, - {0x30, 0x23}, {0x40, 0x24}, - {0x50, 0x25}, {0x60, 0x26}, - {0x70, 0x27}, {0x80, 0x28}, - {0x90, 0x29}, {0xa0, 0x2a}, - {0xb0, 0x2b}, {0xc0, 0x2c}, - {0xd0, 0x2d}, {0xe0, 0x2e}, - {0xf0, 0x2f}, {0xff, 0x30}); + switch (sn9c102_get_bridge(cam)) { + case BRIDGE_SN9C103: + err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, + {0x0a, 0x14}, {0x40, 0x01}, + {0x20, 0x17}, {0x07, 0x18}, + {0xa0, 0x19}, {0x02, 0x1c}, + {0x03, 0x1d}, {0x0f, 0x1e}, + {0x0c, 0x1f}, {0x00, 0x20}, + {0x10, 0x21}, {0x20, 0x22}, + {0x30, 0x23}, {0x40, 0x24}, + {0x50, 0x25}, {0x60, 0x26}, + {0x70, 0x27}, {0x80, 0x28}, + {0x90, 0x29}, {0xa0, 0x2a}, + {0xb0, 0x2b}, {0xc0, 0x2c}, + {0xd0, 0x2d}, {0xe0, 0x2e}, + {0xf0, 0x2f}, {0xff, 0x30}); + break; + case BRIDGE_SN9C105: + case BRIDGE_SN9C120: + err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02}, + {0x00, 0x03}, {0x1a, 0x04}, + {0x50, 0x05}, {0x20, 0x06}, + {0x10, 0x07}, {0x03, 0x10}, + {0x08, 0x14}, {0xa2, 0x17}, + {0x47, 0x18}, {0x00, 0x19}, + {0x1d, 0x1a}, {0x10, 0x1b}, + {0x02, 0x1c}, {0x03, 0x1d}, + {0x0f, 0x1e}, {0x0c, 0x1f}, + {0x00, 0x20}, {0x29, 0x21}, + {0x40, 0x22}, {0x54, 0x23}, + {0x66, 0x24}, {0x76, 0x25}, + {0x85, 0x26}, {0x94, 0x27}, + {0xa1, 0x28}, {0xae, 0x29}, + {0xbb, 0x2a}, {0xc7, 0x2b}, + {0xd3, 0x2c}, {0xde, 0x2d}, + {0xea, 0x2e}, {0xf4, 0x2f}, + {0xff, 0x30}, {0x00, 0x3F}, + {0xC7, 0x40}, {0x01, 0x41}, + {0x44, 0x42}, {0x00, 0x43}, + {0x44, 0x44}, {0x00, 0x45}, + {0x44, 0x46}, {0x00, 0x47}, + {0xC7, 0x48}, {0x01, 0x49}, + {0xC7, 0x4A}, {0x01, 0x4B}, + {0xC7, 0x4C}, {0x01, 0x4D}, + {0x44, 0x4E}, {0x00, 0x4F}, + {0x44, 0x50}, {0x00, 0x51}, + {0x44, 0x52}, {0x00, 0x53}, + {0xC7, 0x54}, {0x01, 0x55}, + {0xC7, 0x56}, {0x01, 0x57}, + {0xC7, 0x58}, {0x01, 0x59}, + {0x44, 0x5A}, {0x00, 0x5B}, + {0x44, 0x5C}, {0x00, 0x5D}, + {0x44, 0x5E}, {0x00, 0x5F}, + {0xC7, 0x60}, {0x01, 0x61}, + {0xC7, 0x62}, {0x01, 0x63}, + {0xC7, 0x64}, {0x01, 0x65}, + {0x44, 0x66}, {0x00, 0x67}, + {0x44, 0x68}, {0x00, 0x69}, + {0x44, 0x6A}, {0x00, 0x6B}, + {0xC7, 0x6C}, {0x01, 0x6D}, + {0xC7, 0x6E}, {0x01, 0x6F}, + {0xC7, 0x70}, {0x01, 0x71}, + {0x44, 0x72}, {0x00, 0x73}, + {0x44, 0x74}, {0x00, 0x75}, + {0x44, 0x76}, {0x00, 0x77}, + {0xC7, 0x78}, {0x01, 0x79}, + {0xC7, 0x7A}, {0x01, 0x7B}, + {0xC7, 0x7C}, {0x01, 0x7D}, + {0x44, 0x7E}, {0x00, 0x7F}, + {0x14, 0x84}, {0x00, 0x85}, + {0x27, 0x86}, {0x00, 0x87}, + {0x07, 0x88}, {0x00, 0x89}, + {0xEC, 0x8A}, {0x0f, 0x8B}, + {0xD8, 0x8C}, {0x0f, 0x8D}, + {0x3D, 0x8E}, {0x00, 0x8F}, + {0x3D, 0x90}, {0x00, 0x91}, + {0xCD, 0x92}, {0x0f, 0x93}, + {0xf7, 0x94}, {0x0f, 0x95}, + {0x0C, 0x96}, {0x00, 0x97}, + {0x00, 0x98}, {0x66, 0x99}, + {0x05, 0x9A}, {0x00, 0x9B}, + {0x04, 0x9C}, {0x00, 0x9D}, + {0x08, 0x9E}, {0x00, 0x9F}, + {0x2D, 0xC0}, {0x2D, 0xC1}, + {0x3A, 0xC2}, {0x05, 0xC3}, + {0x04, 0xC4}, {0x3F, 0xC5}, + {0x00, 0xC6}, {0x00, 0xC7}, + {0x50, 0xC8}, {0x3C, 0xC9}, + {0x28, 0xCA}, {0xD8, 0xCB}, + {0x14, 0xCC}, {0xEC, 0xCD}, + {0x32, 0xCE}, {0xDD, 0xCF}, + {0x32, 0xD0}, {0xDD, 0xD1}, + {0x6A, 0xD2}, {0x50, 0xD3}, + {0x00, 0xD4}, {0x00, 0xD5}, + {0x00, 0xD6}); + break; + default: + break; + } err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d, 0x00, 0x01, 0, 0); @@ -65,50 +150,50 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam, struct v4l2_control* ctrl) { struct sn9c102_sensor* s = sn9c102_get_sensor(cam); - u8 data[5+1]; + u8 data[2]; switch (ctrl->id) { case V4L2_CID_EXPOSURE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2, + data) < 0) return -EIO; - ctrl->value = data[2]; + ctrl->value = data[0]; return 0; case V4L2_CID_GAIN: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2, + data) < 0) return -EIO; - ctrl->value = data[3]; + ctrl->value = data[1]; return 0; case V4L2_CID_RED_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2, + data) < 0) return -EIO; - ctrl->value = data[3]; + ctrl->value = data[1]; return 0; case V4L2_CID_BLUE_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2, + data) < 0) return -EIO; - ctrl->value = data[3]; + ctrl->value = data[1]; return 0; case SN9C102_V4L2_CID_GREEN_BALANCE: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2, + data) < 0) return -EIO; - ctrl->value = data[3]; + ctrl->value = data[1]; return 0; case V4L2_CID_HFLIP: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2, + data) < 0) return -EIO; - ctrl->value = data[3] & 0x20 ? 1 : 0; + ctrl->value = data[1] & 0x20 ? 1 : 0; return 0; case V4L2_CID_VFLIP: - if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, - 2+1, data) < 0) + if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2, + data) < 0) return -EIO; - ctrl->value = data[3] & 0x80 ? 1 : 0; + ctrl->value = data[1] & 0x80 ? 1 : 0; return 0; default: return -EINVAL; @@ -178,8 +263,19 @@ static int mi0360_set_crop(struct sn9c102_device* cam, { struct sn9c102_sensor* s = sn9c102_get_sensor(cam); int err = 0; - u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0, - v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; + u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; + + switch (sn9c102_get_bridge(cam)) { + case BRIDGE_SN9C103: + h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0; + break; + case BRIDGE_SN9C105: + case BRIDGE_SN9C120: + h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1; + break; + default: + break; + } err += sn9c102_write_reg(cam, h_start, 0x12); err += sn9c102_write_reg(cam, v_start, 0x13); @@ -194,24 +290,30 @@ static int mi0360_set_pix_format(struct sn9c102_device* cam, struct sn9c102_sensor* s = sn9c102_get_sensor(cam); int err = 0; - if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { - err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, - 0x0a, 0x00, 0x02, 0, 0); - err += sn9c102_write_reg(cam, 0x20, 0x19); - } else { + if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0a, 0x00, 0x05, 0, 0); err += sn9c102_write_reg(cam, 0x60, 0x19); + if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 || + sn9c102_get_bridge(cam) == BRIDGE_SN9C120) + err += sn9c102_write_reg(cam, 0xa6, 0x17); + } else { + err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, + 0x0a, 0x00, 0x02, 0, 0); + err += sn9c102_write_reg(cam, 0x20, 0x19); + if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 || + sn9c102_get_bridge(cam) == BRIDGE_SN9C120) + err += sn9c102_write_reg(cam, 0xa2, 0x17); } return err; } -static struct sn9c102_sensor mi0360 = { +static const struct sn9c102_sensor mi0360 = { .name = "MI-0360", .maintainer = "Luca Risolia ", - .supported_bridge = BRIDGE_SN9C103, + .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120, .frequency = SN9C102_I2C_100KHZ, .interface = SN9C102_I2C_2WIRES, .i2c_slave_id = 0x5d, @@ -317,19 +419,31 @@ static struct sn9c102_sensor mi0360 = { int sn9c102_probe_mi0360(struct sn9c102_device* cam) { - u8 data[5+1]; - int err; - err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, - {0x28, 0x17}); - if (err) - return -EIO; + u8 data[2]; + + switch (sn9c102_get_bridge(cam)) { + case BRIDGE_SN9C103: + if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, + {0x28, 0x17})) + return -EIO; + break; + case BRIDGE_SN9C105: + case BRIDGE_SN9C120: + if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1}, + {0x01, 0x01}, {0x00, 0x01}, + {0x28, 0x17})) + return -EIO; + break; + default: + break; + } if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00, - 2+1, data) < 0) + 2, data) < 0) return -EIO; - if (data[2] != 0x82 || data[3] != 0x43) + if (data[0] != 0x82 || data[1] != 0x43) return -ENODEV; sn9c102_attach_sensor(cam, &mi0360); diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c b/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c index 31b6080b0615..e6832347894f 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_ov7630.c @@ -29,9 +29,8 @@ static int ov7630_init(struct sn9c102_device* cam) switch (sn9c102_get_bridge(cam)) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: - err = sn9c102_write_const_regs(cam, {0x00, 0x14}, - {0x60, 0x17}, {0x0f, 0x18}, - {0x50, 0x19}); + err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, + {0x0f, 0x18}, {0x50, 0x19}); err += sn9c102_i2c_write(cam, 0x12, 0x8d); err += sn9c102_i2c_write(cam, 0x12, 0x0d); @@ -61,7 +60,6 @@ static int ov7630_init(struct sn9c102_device* cam) err += sn9c102_i2c_write(cam, 0x71, 0x00); err += sn9c102_i2c_write(cam, 0x74, 0x21); err += sn9c102_i2c_write(cam, 0x7d, 0xf7); - break; case BRIDGE_SN9C103: err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03}, @@ -253,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor ov7630 = { +static const struct sn9c102_sensor ov7630 = { .name = "OV7630", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, @@ -408,19 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam) switch (sn9c102_get_bridge(cam)) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: - err = sn9c102_write_const_regs(cam, {0x01, 0x01}, - {0x00, 0x01}, {0x28, 0x17}); - + err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01}, + {0x28, 0x17}); break; case BRIDGE_SN9C103: /* do _not_ change anything! */ - err = sn9c102_write_const_regs(cam, {0x09, 0x01}, - {0x42, 0x01}, {0x28, 0x17}, - {0x44, 0x02}); + err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01}, + {0x28, 0x17}, {0x44, 0x02}); pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a); - if (err || pid < 0) { /* try a different initialization */ - err = sn9c102_write_reg(cam, 0x01, 0x01); - err += sn9c102_write_reg(cam, 0x00, 0x01); - } + if (err || pid < 0) /* try a different initialization */ + err += sn9c102_write_const_regs(cam, {0x01, 0x01}, + {0x00, 0x01}); break; default: break; diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c b/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c index c898e948fe8d..4b6474048a72 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_ov7660.c @@ -104,8 +104,8 @@ static int ov7660_init(struct sn9c102_device* cam) err += sn9c102_i2c_write(cam, 0x12, 0x80); err += sn9c102_i2c_write(cam, 0x11, 0x09); err += sn9c102_i2c_write(cam, 0x00, 0x0A); - err += sn9c102_i2c_write(cam, 0x01, 0x78); - err += sn9c102_i2c_write(cam, 0x02, 0x90); + err += sn9c102_i2c_write(cam, 0x01, 0x80); + err += sn9c102_i2c_write(cam, 0x02, 0x80); err += sn9c102_i2c_write(cam, 0x03, 0x00); err += sn9c102_i2c_write(cam, 0x04, 0x00); err += sn9c102_i2c_write(cam, 0x05, 0x08); @@ -122,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam) err += sn9c102_i2c_write(cam, 0x10, 0x20); err += sn9c102_i2c_write(cam, 0x11, 0x03); err += sn9c102_i2c_write(cam, 0x12, 0x05); - err += sn9c102_i2c_write(cam, 0x13, 0xF8); + err += sn9c102_i2c_write(cam, 0x13, 0xC7); err += sn9c102_i2c_write(cam, 0x14, 0x2C); err += sn9c102_i2c_write(cam, 0x15, 0x00); err += sn9c102_i2c_write(cam, 0x16, 0x02); @@ -162,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam) err += sn9c102_i2c_write(cam, 0x38, 0x02); err += sn9c102_i2c_write(cam, 0x39, 0x43); err += sn9c102_i2c_write(cam, 0x3A, 0x00); - err += sn9c102_i2c_write(cam, 0x3B, 0x02); + err += sn9c102_i2c_write(cam, 0x3B, 0x0A); err += sn9c102_i2c_write(cam, 0x3C, 0x6C); err += sn9c102_i2c_write(cam, 0x3D, 0x99); err += sn9c102_i2c_write(cam, 0x3E, 0x0E); @@ -281,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam, return -EIO; break; case V4L2_CID_DO_WHITE_BALANCE: - ctrl->value = sn9c102_pread_reg(cam, 0x02); + if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0) + return -EIO; ctrl->value = (ctrl->value & 0x04) ? 1 : 0; break; case V4L2_CID_RED_BALANCE: - ctrl->value = sn9c102_pread_reg(cam, 0x05); + if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0) + return -EIO; ctrl->value &= 0x7f; break; case V4L2_CID_BLUE_BALANCE: - ctrl->value = sn9c102_pread_reg(cam, 0x06); + if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0) + return -EIO; ctrl->value &= 0x7f; break; case SN9C102_V4L2_CID_GREEN_BALANCE: - ctrl->value = sn9c102_pread_reg(cam, 0x07); + if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0) + return -EIO; ctrl->value &= 0x7f; break; + case SN9C102_V4L2_CID_BAND_FILTER: + if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0) + return -EIO; + ctrl->value &= 0x08; + break; case V4L2_CID_GAIN: if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0) return -EIO; - ctrl->value &= 0x7f; + ctrl->value &= 0x1f; break; case V4L2_CID_AUTOGAIN: if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0) @@ -335,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam, case SN9C102_V4L2_CID_GREEN_BALANCE: err += sn9c102_write_reg(cam, ctrl->value, 0x07); break; + case SN9C102_V4L2_CID_BAND_FILTER: + err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b); + break; case V4L2_CID_GAIN: - err += sn9c102_i2c_write(cam, 0x00, ctrl->value); + err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value); break; case V4L2_CID_AUTOGAIN: - err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value | - (ctrl->value << 1)); + err += sn9c102_i2c_write(cam, 0x13, 0xc0 | + (ctrl->value * 0x07)); break; default: return -EINVAL; @@ -386,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor ov7660 = { +static const struct sn9c102_sensor ov7660 = { .name = "OV7660", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120, @@ -401,9 +413,9 @@ static struct sn9c102_sensor ov7660 = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "global gain", .minimum = 0x00, - .maximum = 0x7f, + .maximum = 0x1f, .step = 0x01, - .default_value = 0x0a, + .default_value = 0x09, .flags = 0, }, { @@ -413,7 +425,7 @@ static struct sn9c102_sensor ov7660 = { .minimum = 0x00, .maximum = 0xff, .step = 0x01, - .default_value = 0x50, + .default_value = 0x27, .flags = 0, }, { @@ -433,7 +445,7 @@ static struct sn9c102_sensor ov7660 = { .minimum = 0x00, .maximum = 0x7f, .step = 0x01, - .default_value = 0x1f, + .default_value = 0x14, .flags = 0, }, { @@ -443,7 +455,7 @@ static struct sn9c102_sensor ov7660 = { .minimum = 0x00, .maximum = 0x7f, .step = 0x01, - .default_value = 0x1e, + .default_value = 0x14, .flags = 0, }, { @@ -453,7 +465,7 @@ static struct sn9c102_sensor ov7660 = { .minimum = 0x00, .maximum = 0x01, .step = 0x01, - .default_value = 0x00, + .default_value = 0x01, .flags = 0, }, { @@ -463,7 +475,17 @@ static struct sn9c102_sensor ov7660 = { .minimum = 0x00, .maximum = 0x7f, .step = 0x01, - .default_value = 0x20, + .default_value = 0x14, + .flags = 0, + }, + { + .id = SN9C102_V4L2_CID_BAND_FILTER, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "band filter", + .minimum = 0x00, + .maximum = 0x01, + .step = 0x01, + .default_value = 0x00, .flags = 0, }, }, @@ -508,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam) return -EIO; if (pid != 0x76 || ver != 0x60) return -ENODEV; + sn9c102_attach_sensor(cam, &ov7660); return 0; diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c b/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c index 67151964801f..360f2a848bc0 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_pas106b.c @@ -163,7 +163,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor pas106b = { +static const struct sn9c102_sensor pas106b = { .name = "PAS106B", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, @@ -273,23 +273,21 @@ static struct sn9c102_sensor pas106b = { int sn9c102_probe_pas106b(struct sn9c102_device* cam) { - int r0 = 0, r1 = 0, err; + int r0 = 0, r1 = 0; unsigned int pid = 0; /* Minimal initialization to enable the I2C communication NOTE: do NOT change the values! */ - err = sn9c102_write_const_regs(cam, - {0x01, 0x01}, /* sensor power down */ - {0x00, 0x01}, /* sensor power on */ - {0x28, 0x17});/* sensor clock 24 MHz */ - if (err) + if (sn9c102_write_const_regs(cam, + {0x01, 0x01}, /* sensor power down */ + {0x00, 0x01}, /* sensor power on */ + {0x28, 0x17})) /* sensor clock at 24 MHz */ return -EIO; r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00); r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01); - if (r0 < 0 || r1 < 0) return -EIO; diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c index c1b8d6b63b47..ca4a1506ed3d 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_pas202bcb.c @@ -35,29 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam) switch (sn9c102_get_bridge(cam)) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: - err = sn9c102_write_const_regs(cam, {0x00, 0x10}, - {0x00, 0x11}, {0x00, 0x14}, - {0x20, 0x17}, {0x30, 0x19}, - {0x09, 0x18}); + err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, + {0x00, 0x14}, {0x20, 0x17}, + {0x30, 0x19}, {0x09, 0x18}); break; case BRIDGE_SN9C103: - err = sn9c102_write_const_regs(cam, {0x00, 0x02}, - {0x00, 0x03}, {0x1a, 0x04}, - {0x20, 0x05}, {0x20, 0x06}, - {0x20, 0x07}, {0x00, 0x10}, - {0x00, 0x11}, {0x00, 0x14}, - {0x20, 0x17}, {0x30, 0x19}, - {0x09, 0x18}, {0x02, 0x1c}, - {0x03, 0x1d}, {0x0f, 0x1e}, - {0x0c, 0x1f}, {0x00, 0x20}, - {0x10, 0x21}, {0x20, 0x22}, - {0x30, 0x23}, {0x40, 0x24}, - {0x50, 0x25}, {0x60, 0x26}, - {0x70, 0x27}, {0x80, 0x28}, - {0x90, 0x29}, {0xa0, 0x2a}, - {0xb0, 0x2b}, {0xc0, 0x2c}, - {0xd0, 0x2d}, {0xe0, 0x2e}, - {0xf0, 0x2f}, {0xff, 0x30}); + err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03}, + {0x1a, 0x04}, {0x20, 0x05}, + {0x20, 0x06}, {0x20, 0x07}, + {0x00, 0x10}, {0x00, 0x11}, + {0x00, 0x14}, {0x20, 0x17}, + {0x30, 0x19}, {0x09, 0x18}, + {0x02, 0x1c}, {0x03, 0x1d}, + {0x0f, 0x1e}, {0x0c, 0x1f}, + {0x00, 0x20}, {0x10, 0x21}, + {0x20, 0x22}, {0x30, 0x23}, + {0x40, 0x24}, {0x50, 0x25}, + {0x60, 0x26}, {0x70, 0x27}, + {0x80, 0x28}, {0x90, 0x29}, + {0xa0, 0x2a}, {0xb0, 0x2b}, + {0xc0, 0x2c}, {0xd0, 0x2d}, + {0xe0, 0x2e}, {0xf0, 0x2f}, + {0xff, 0x30}); break; default: break; @@ -197,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam, } -static struct sn9c102_sensor pas202bcb = { +static const struct sn9c102_sensor pas202bcb = { .name = "PAS202BCB", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, @@ -313,9 +312,8 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam) {0x28, 0x17});/* clock 24 MHz */ break; case BRIDGE_SN9C103: /* do _not_ change anything! */ - err = sn9c102_write_const_regs(cam, {0x09, 0x01}, - {0x44, 0x01}, {0x44, 0x02}, - {0x29, 0x17}); + err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01}, + {0x44, 0x02}, {0x29, 0x17}); break; default: break; diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_sensor.h b/trunk/drivers/media/video/sn9c102/sn9c102_sensor.h index 1bbf64c897a2..2d7d786b8430 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/trunk/drivers/media/video/sn9c102/sn9c102_sensor.h @@ -22,7 +22,7 @@ #define _SN9C102_SENSOR_H_ #include -#include +#include #include #include #include @@ -74,7 +74,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id); /* Attach a probed sensor to the camera. */ extern void sn9c102_attach_sensor(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor); + const struct sn9c102_sensor* sensor); /* Read/write routines: they always return -1 on error, 0 or the read value @@ -85,10 +85,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, */ /* The "try" I2C I/O versions are used when probing the sensor */ -extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*, - u8 address, u8 value); -extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, - u8 address); +extern int sn9c102_i2c_try_write(struct sn9c102_device*, + const struct sn9c102_sensor*, u8 address, + u8 value); +extern int sn9c102_i2c_try_read(struct sn9c102_device*, + const struct sn9c102_sensor*, u8 address); /* These must be used if and only if the sensor doesn't implement the standard @@ -102,29 +103,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, byte. */ extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 n, + const struct sn9c102_sensor* sensor, u8 n, u8 data0, u8 data1, u8 data2, u8 data3, u8 data4, u8 data5); extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, - struct sn9c102_sensor* sensor, u8 data0, - u8 data1, u8 n, u8 buffer[]); + const struct sn9c102_sensor* sensor, + u8 data0, u8 data1, u8 n, u8 buffer[]); /* To be used after the sensor struct has been attached to the camera struct */ extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value); extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address); /* I/O on registers in the bridge. Could be used by the sensor methods too */ +extern int sn9c102_read_reg(struct sn9c102_device*, u16 index); extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index); extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2], int count); /* - * Write multiple registers with constant values. For example: - * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); - */ -#define sn9c102_write_const_regs(device, data...) \ - ({ const static u8 _data[][2] = {data}; \ - sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); }) + Write multiple registers with constant values. For example: + sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18}); + Register adresses must be < 256. +*/ +#define sn9c102_write_const_regs(sn9c102_device, data...) \ + ({ const static u8 _valreg[][2] = {data}; \ + sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); }) /*****************************************************************************/ diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c index 0e7ec8662c70..e7d2de2bace1 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c @@ -88,7 +88,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor tas5110c1b = { +static const struct sn9c102_sensor tas5110c1b = { .name = "TAS5110C1B", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c index 83a39e8b5e71..d32fdbccdc5e 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5110d.c @@ -68,7 +68,7 @@ static int tas5110d_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor tas5110d = { +static const struct sn9c102_sensor tas5110d = { .name = "TAS5110D", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, diff --git a/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c index 50406503fc40..56fb1d575a8a 100644 --- a/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c +++ b/trunk/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c @@ -89,7 +89,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, } -static struct sn9c102_sensor tas5130d1b = { +static const struct sn9c102_sensor tas5130d1b = { .name = "TAS5130D1B", .maintainer = "Luca Risolia ", .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102, diff --git a/trunk/drivers/media/video/usbvideo/Kconfig b/trunk/drivers/media/video/usbvideo/Kconfig index a0fd82b924f2..e4cb99c1f94b 100644 --- a/trunk/drivers/media/video/usbvideo/Kconfig +++ b/trunk/drivers/media/video/usbvideo/Kconfig @@ -3,7 +3,7 @@ config VIDEO_USBVIDEO config USB_VICAM tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" - depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL + depends on VIDEO_V4L1 && EXPERIMENTAL select VIDEO_USBVIDEO ---help--- Say Y here if you have 3com homeconnect camera (vicam). @@ -13,7 +13,7 @@ config USB_VICAM config USB_IBMCAM tristate "USB IBM (Xirlink) C-it Camera support" - depends on USB && VIDEO_DEV && VIDEO_V4L1 + depends on VIDEO_V4L1 select VIDEO_USBVIDEO ---help--- Say Y here if you want to connect a IBM "C-It" camera, also known as @@ -28,7 +28,7 @@ config USB_IBMCAM config USB_KONICAWC tristate "USB Konica Webcam support" - depends on USB && VIDEO_DEV && VIDEO_V4L1 + depends on VIDEO_V4L1 select VIDEO_USBVIDEO ---help--- Say Y here if you want support for webcams based on a Konica @@ -39,7 +39,7 @@ config USB_KONICAWC config USB_QUICKCAM_MESSENGER tristate "USB Logitech Quickcam Messenger" - depends on USB && VIDEO_DEV && VIDEO_V4L1 + depends on VIDEO_V4L1 select VIDEO_USBVIDEO ---help--- Say Y or M here to enable support for the USB Logitech Quickcam diff --git a/trunk/drivers/media/video/usbvision/Kconfig b/trunk/drivers/media/video/usbvision/Kconfig index c43a5d899091..fc24ef05b3f3 100644 --- a/trunk/drivers/media/video/usbvision/Kconfig +++ b/trunk/drivers/media/video/usbvision/Kconfig @@ -1,6 +1,6 @@ config VIDEO_USBVISION tristate "USB video devices based on Nogatech NT1003/1004/1005" - depends on I2C && VIDEO_V4L2 && USB + depends on I2C && VIDEO_V4L2 select VIDEO_TUNER select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO ---help--- diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index a861e150865e..ede8543818bf 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -127,7 +127,7 @@ set_v4l_control(struct inode *inode, /* ----------------------------------------------------------------- */ -static int palette2pixelformat[] = { +const static unsigned int palette2pixelformat[] = { [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY, [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555, [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565, @@ -145,7 +145,7 @@ static int palette2pixelformat[] = { [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P, }; -static unsigned int +static unsigned int __attribute_pure__ palette_to_pixelformat(unsigned int palette) { if (palette < ARRAY_SIZE(palette2pixelformat)) @@ -154,8 +154,8 @@ palette_to_pixelformat(unsigned int palette) return 0; } -static unsigned int -pixelformat_to_palette(int pixelformat) +static unsigned int __attribute_const__ +pixelformat_to_palette(unsigned int pixelformat) { int palette = 0; switch (pixelformat) @@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode *inode, case VIDIOCSPICT: /* set tone controls & partial capture format */ { struct video_picture *pict = arg; + int mem_err = 0, ovl_err = 0; + memset(&fbuf2, 0, sizeof(fbuf2)); set_v4l_control(inode, file, @@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode *inode, V4L2_CID_SATURATION, pict->colour, drv); set_v4l_control(inode, file, V4L2_CID_WHITENESS, pict->whiteness, drv); + /* + * V4L1 uses this ioctl to set both memory capture and overlay + * pixel format, while V4L2 has two different ioctls for this. + * Some cards may not support one or the other, and may support + * different pixel formats for memory vs overlay. + */ fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(inode, file, VIDIOC_G_FMT, fmt2); - if (err < 0) + /* If VIDIOC_G_FMT failed, then the driver likely doesn't + support memory capture. Trying to set the memory capture + parameters would be pointless. */ + if (err < 0) { dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); - if (fmt2->fmt.pix.pixelformat != - palette_to_pixelformat(pict->palette)) { + mem_err = -1000; /* didn't even try */ + } else if (fmt2->fmt.pix.pixelformat != + palette_to_pixelformat(pict->palette)) { fmt2->fmt.pix.pixelformat = palette_to_pixelformat( pict->palette); - err = drv(inode, file, VIDIOC_S_FMT, fmt2); - if (err < 0) - dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err); + mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2); + if (mem_err < 0) + dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", + mem_err); } err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); - if (err < 0) + /* If VIDIOC_G_FBUF failed, then the driver likely doesn't + support overlay. Trying to set the overlay parameters + would be quite pointless. */ + if (err < 0) { dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err); - if (fbuf2.fmt.pixelformat != - palette_to_pixelformat(pict->palette)) { + ovl_err = -1000; /* didn't even try */ + } else if (fbuf2.fmt.pixelformat != + palette_to_pixelformat(pict->palette)) { fbuf2.fmt.pixelformat = palette_to_pixelformat( pict->palette); - err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); - if (err < 0) - dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err); - err = 0; /* likely fails for non-root */ + ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); + if (ovl_err < 0) + dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", + ovl_err); } + if (ovl_err < 0 && mem_err < 0) + /* ioctl failed, couldn't set either parameter */ + if (mem_err != -1000) { + err = mem_err; + } else if (ovl_err == -EPERM) { + err = 0; + } else { + err = ovl_err; + } + else + err = 0; break; } case VIDIOCGTUNER: /* get tuner information */ diff --git a/trunk/drivers/media/video/video-buf.c b/trunk/drivers/media/video/video-buf.c index 459786ff459a..a32dfbe0585a 100644 --- a/trunk/drivers/media/video/video-buf.c +++ b/trunk/drivers/media/video/video-buf.c @@ -702,9 +702,7 @@ videobuf_qbuf(struct videobuf_queue *q, dprintk(1,"qbuf: memory type is wrong.\n"); goto done; } - if (buf->state == STATE_QUEUED || - buf->state == STATE_PREPARED || - buf->state == STATE_ACTIVE) { + if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; } diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 5263b50463e1..b876aca69c73 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -433,13 +433,43 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, int ret = -EINVAL; if ( (vfd->debug & V4L2_DEBUG_IOCTL) && - !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) { + !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { v4l_print_ioctl(vfd->name, cmd); } +#ifdef CONFIG_VIDEO_V4L1_COMPAT + /*********************************************************** + Handles calls to the obsoleted V4L1 API + Due to the nature of VIDIOCGMBUF, each driver that supports + V4L1 should implement its own handler for this ioctl. + ***********************************************************/ + + /* --- streaming capture ------------------------------------- */ + if (cmd == VIDIOCGMBUF) { + struct video_mbuf *p=arg; + + memset(p,0,sizeof(p)); + + if (!vfd->vidiocgmbuf) + return ret; + ret=vfd->vidiocgmbuf(file, fh, p); + if (!ret) + dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", + p->size, p->frames, + (unsigned long)p->offsets); + return ret; + } + + /******************************************************** + All other V4L1 calls are handled by v4l1_compat module. + Those calls will be translated into V4L2 calls, and + __video_do_ioctl will be called again, with one or more + V4L2 ioctls. + ********************************************************/ if (_IOC_TYPE(cmd)=='v') return v4l_compat_translate_ioctl(inode,file,cmd,arg, __video_do_ioctl); +#endif switch(cmd) { /* --- capabilities ------------------------------------------ */ @@ -791,24 +821,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_overlay(file, fh, *i); break; } -#ifdef CONFIG_VIDEO_V4L1_COMPAT - /* --- streaming capture ------------------------------------- */ - case VIDIOCGMBUF: - { - struct video_mbuf *p=arg; - - memset(p,0,sizeof(p)); - - if (!vfd->vidiocgmbuf) - break; - ret=vfd->vidiocgmbuf(file, fh, p); - if (!ret) - dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", - p->size, p->frames, - (unsigned long)p->offsets); - break; - } -#endif case VIDIOC_G_FBUF: { struct v4l2_framebuffer *p=arg; diff --git a/trunk/drivers/media/video/zc0301/Kconfig b/trunk/drivers/media/video/zc0301/Kconfig index a859a6920189..47cd93f9c7de 100644 --- a/trunk/drivers/media/video/zc0301/Kconfig +++ b/trunk/drivers/media/video/zc0301/Kconfig @@ -1,6 +1,6 @@ config USB_ZC0301 tristate "USB ZC0301[P] Image Processor and Control Chip support" - depends on USB && VIDEO_V4L1 + depends on VIDEO_V4L1 ---help--- Say Y here if you want support for cameras based on the ZC0301 or ZC0301P Image Processors and Control Chips. diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index fa489b10c38c..8a7f9e9fb8d8 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1898,8 +1898,12 @@ endmenu # Gigabit Ethernet # -menu "Ethernet (1000 Mbit)" +menuconfig NETDEV_1000 + bool "Ethernet (1000 Mbit)" depends on !UML + default y + +if NETDEV_1000 config ACENIC tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support" @@ -2326,14 +2330,18 @@ config ATL1 To compile this driver as a module, choose M here. The module will be called atl1. -endmenu +endif # NETDEV_1000 # # 10 Gigabit Ethernet # -menu "Ethernet (10000 Mbit)" +menuconfig NETDEV_10000 + bool "Ethernet (10000 Mbit)" depends on !UML + default y + +if NETDEV_10000 config CHELSIO_T1 tristate "Chelsio 10Gb Ethernet support" @@ -2507,7 +2515,7 @@ config MLX4_DEBUG debug_level module parameter (which can also be set after the driver is loaded through sysfs). -endmenu +endif # NETDEV_10000 source "drivers/net/tokenring/Kconfig" diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index acf1c801a1b8..af016d0ea1c6 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -623,7 +623,7 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev) priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1; } else { err = request_irq(dev->pdev->irq, mlx4_interrupt, - SA_SHIRQ, DRV_NAME, dev); + IRQF_SHARED, DRV_NAME, dev); if (err) goto err_out_async; diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 4e32bb678ea9..2c5c6d20e6e9 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -735,7 +735,7 @@ static int netxen_nic_open(struct net_device *netdev) } adapter->irq = adapter->ahw.pdev->irq; err = request_irq(adapter->ahw.pdev->irq, netxen_intr, - SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, + IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name, adapter); if (err) { printk(KERN_ERR "request_irq failed with: %d\n", err); diff --git a/trunk/drivers/net/pcmcia/Kconfig b/trunk/drivers/net/pcmcia/Kconfig index 74f862001247..5d658bc9791c 100644 --- a/trunk/drivers/net/pcmcia/Kconfig +++ b/trunk/drivers/net/pcmcia/Kconfig @@ -2,11 +2,9 @@ # PCMCIA Network device configuration # -menu "PCMCIA network device support" - depends on NETDEVICES && PCMCIA!=n - -config NET_PCMCIA +menuconfig NET_PCMCIA bool "PCMCIA network device support" + depends on PCMCIA ---help--- Say Y if you would like to include support for any PCMCIA or CardBus network adapters, then say Y to the driver for your particular card @@ -21,9 +19,10 @@ config NET_PCMCIA If unsure, say N. +if NET_PCMCIA + config PCMCIA_3C589 tristate "3Com 3c589 PCMCIA support" - depends on NET_PCMCIA && PCMCIA help Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA (PC-card) Ethernet card to your computer. @@ -33,7 +32,6 @@ config PCMCIA_3C589 config PCMCIA_3C574 tristate "3Com 3c574 PCMCIA support" - depends on NET_PCMCIA && PCMCIA help Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA (PC-card) Fast Ethernet card to your computer. @@ -43,7 +41,6 @@ config PCMCIA_3C574 config PCMCIA_FMVJ18X tristate "Fujitsu FMV-J18x PCMCIA support" - depends on NET_PCMCIA && PCMCIA select CRC32 help Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible @@ -54,7 +51,6 @@ config PCMCIA_FMVJ18X config PCMCIA_PCNET tristate "NE2000 compatible PCMCIA support" - depends on NET_PCMCIA && PCMCIA select CRC32 help Say Y here if you intend to attach an NE2000 compatible PCMCIA @@ -65,7 +61,6 @@ config PCMCIA_PCNET config PCMCIA_NMCLAN tristate "New Media PCMCIA support" - depends on NET_PCMCIA && PCMCIA help Say Y here if you intend to attach a New Media Ethernet or LiveWire PCMCIA (PC-card) Ethernet card to your computer. @@ -75,7 +70,6 @@ config PCMCIA_NMCLAN config PCMCIA_SMC91C92 tristate "SMC 91Cxx PCMCIA support" - depends on NET_PCMCIA && PCMCIA select CRC32 select MII help @@ -87,7 +81,6 @@ config PCMCIA_SMC91C92 config PCMCIA_XIRC2PS tristate "Xircom 16-bit PCMCIA support" - depends on NET_PCMCIA && PCMCIA help Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card) Ethernet or Fast Ethernet card to your computer. @@ -97,7 +90,6 @@ config PCMCIA_XIRC2PS config PCMCIA_AXNET tristate "Asix AX88190 PCMCIA support" - depends on NET_PCMCIA && PCMCIA ---help--- Say Y here if you intend to attach an Asix AX88190-based PCMCIA (PC-card) Fast Ethernet card to your computer. These cards are @@ -109,7 +101,7 @@ config PCMCIA_AXNET config ARCNET_COM20020_CS tristate "COM20020 ARCnet PCMCIA support" - depends on NET_PCMCIA && ARCNET_COM20020 && PCMCIA + depends on ARCNET_COM20020 help Say Y here if you intend to attach this type of ARCnet PCMCIA card to your computer. @@ -119,7 +111,7 @@ config ARCNET_COM20020_CS config PCMCIA_IBMTR tristate "IBM PCMCIA tokenring adapter support" - depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA && !64BIT + depends on IBMTR!=y && TR && !64BIT help Say Y here if you intend to attach this type of Token Ring PCMCIA card to your computer. You then also need to say Y to "Token Ring @@ -128,5 +120,4 @@ config PCMCIA_IBMTR To compile this driver as a module, choose M here: the module will be called ibmtr_cs. -endmenu - +endif # NET_PCMCIA diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index c0d3101eb6a0..09b6f259eb92 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -2,70 +2,61 @@ # PHY Layer Configuration # -menu "PHY device support" - depends on !S390 - -config PHYLIB +menuconfig PHYLIB tristate "PHY Device support and infrastructure" + depends on !S390 depends on NET_ETHERNET && (BROKEN || !S390) help Ethernet controllers are usually attached to PHY devices. This option provides infrastructure for managing PHY devices. +if PHYLIB + comment "MII PHY device drivers" - depends on PHYLIB config MARVELL_PHY tristate "Drivers for Marvell PHYs" - depends on PHYLIB ---help--- Currently has a driver for the 88E1011S config DAVICOM_PHY tristate "Drivers for Davicom PHYs" - depends on PHYLIB ---help--- Currently supports dm9161e and dm9131 config QSEMI_PHY tristate "Drivers for Quality Semiconductor PHYs" - depends on PHYLIB ---help--- Currently supports the qs6612 config LXT_PHY tristate "Drivers for the Intel LXT PHYs" - depends on PHYLIB ---help--- Currently supports the lxt970, lxt971 config CICADA_PHY tristate "Drivers for the Cicada PHYs" - depends on PHYLIB ---help--- Currently supports the cis8204 + config VITESSE_PHY tristate "Drivers for the Vitesse PHYs" - depends on PHYLIB ---help--- Currently supports the vsc8244 config SMSC_PHY tristate "Drivers for SMSC PHYs" - depends on PHYLIB ---help--- Currently supports the LAN83C185 PHY config BROADCOM_PHY tristate "Drivers for Broadcom PHYs" - depends on PHYLIB ---help--- Currently supports the BCM5411, BCM5421 and BCM5461 PHYs. config FIXED_PHY tristate "Drivers for PHY emulation on fixed speed/link" - depends on PHYLIB ---help--- Adds the driver to PHY layer to cover the boards that do not have any PHY bound, but with the ability to manipulate the speed/link in software. The relevant MII @@ -80,5 +71,4 @@ config FIXED_MII_100_FDX bool "Emulation for 100M Fdx fixed PHY behavior" depends on FIXED_PHY -endmenu - +endif # PHYLIB diff --git a/trunk/drivers/net/phy/davicom.c b/trunk/drivers/net/phy/davicom.c index 519baa38be8d..7ed632db00d7 100644 --- a/trunk/drivers/net/phy/davicom.c +++ b/trunk/drivers/net/phy/davicom.c @@ -139,7 +139,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev) return (err < 0) ? err : 0; } -static struct phy_driver dm9161_driver = { +static struct phy_driver dm9161e_driver = { .phy_id = 0x0181b880, .name = "Davicom DM9161E", .phy_id_mask = 0x0ffffff0, @@ -147,7 +147,18 @@ static struct phy_driver dm9161_driver = { .config_init = dm9161_config_init, .config_aneg = dm9161_config_aneg, .read_status = genphy_read_status, - .driver = { .owner = THIS_MODULE,}, + .driver = { .owner = THIS_MODULE,}, +}; + +static struct phy_driver dm9161a_driver = { + .phy_id = 0x0181b8a0, + .name = "Davicom DM9161A", + .phy_id_mask = 0x0ffffff0, + .features = PHY_BASIC_FEATURES, + .config_init = dm9161_config_init, + .config_aneg = dm9161_config_aneg, + .read_status = genphy_read_status, + .driver = { .owner = THIS_MODULE,}, }; static struct phy_driver dm9131_driver = { @@ -160,31 +171,38 @@ static struct phy_driver dm9131_driver = { .read_status = genphy_read_status, .ack_interrupt = dm9161_ack_interrupt, .config_intr = dm9161_config_intr, - .driver = { .owner = THIS_MODULE,}, + .driver = { .owner = THIS_MODULE,}, }; static int __init davicom_init(void) { int ret; - ret = phy_driver_register(&dm9161_driver); + ret = phy_driver_register(&dm9161e_driver); if (ret) goto err1; - ret = phy_driver_register(&dm9131_driver); + ret = phy_driver_register(&dm9161a_driver); if (ret) goto err2; + + ret = phy_driver_register(&dm9131_driver); + if (ret) + goto err3; return 0; - err2: - phy_driver_unregister(&dm9161_driver); + err3: + phy_driver_unregister(&dm9161a_driver); + err2: + phy_driver_unregister(&dm9161e_driver); err1: return ret; } static void __exit davicom_exit(void) { - phy_driver_unregister(&dm9161_driver); + phy_driver_unregister(&dm9161e_driver); + phy_driver_unregister(&dm9161a_driver); phy_driver_unregister(&dm9131_driver); } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 290e1c1f30c6..e3e6d410d72c 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -84,7 +84,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.22.1" +#define DRV_VERSION "2.0.23.1" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -281,6 +281,28 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { ("lro_out_of_sequence_pkts"), ("lro_flush_due_to_max_pkts"), ("lro_avg_aggr_pkts"), + ("mem_alloc_fail_cnt"), + ("watchdog_timer_cnt"), + ("mem_allocated"), + ("mem_freed"), + ("link_up_cnt"), + ("link_down_cnt"), + ("link_up_time"), + ("link_down_time"), + ("tx_tcode_buf_abort_cnt"), + ("tx_tcode_desc_abort_cnt"), + ("tx_tcode_parity_err_cnt"), + ("tx_tcode_link_loss_cnt"), + ("tx_tcode_list_proc_err_cnt"), + ("rx_tcode_parity_err_cnt"), + ("rx_tcode_abort_cnt"), + ("rx_tcode_parity_abort_cnt"), + ("rx_tcode_rda_fail_cnt"), + ("rx_tcode_unkn_prot_cnt"), + ("rx_tcode_fcs_err_cnt"), + ("rx_tcode_buf_size_err_cnt"), + ("rx_tcode_rxd_corrupt_cnt"), + ("rx_tcode_unkn_err_cnt") }; #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN @@ -490,6 +512,7 @@ static int init_shared_mem(struct s2io_nic *nic) struct mac_info *mac_control; struct config_param *config; + unsigned long long mem_allocated = 0; mac_control = &nic->mac_control; config = &nic->config; @@ -519,6 +542,7 @@ static int init_shared_mem(struct s2io_nic *nic) "Malloc failed for list_info\n"); return -ENOMEM; } + mem_allocated += list_holder_size; memset(mac_control->fifos[i].list_info, 0, list_holder_size); } for (i = 0; i < config->tx_fifo_num; i++) { @@ -565,6 +589,7 @@ static int init_shared_mem(struct s2io_nic *nic) DBG_PRINT(INFO_DBG, "failed for TxDL\n"); return -ENOMEM; } + mem_allocated += PAGE_SIZE; } while (k < lst_per_page) { int l = (j * lst_per_page) + k; @@ -582,6 +607,7 @@ static int init_shared_mem(struct s2io_nic *nic) nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; + mem_allocated += (size * sizeof(u64)); /* Allocation and initialization of RXDs in Rings */ size = 0; @@ -639,6 +665,7 @@ static int init_shared_mem(struct s2io_nic *nic) rx_blocks->block_virt_addr = tmp_v_addr; return -ENOMEM; } + mem_allocated += size; memset(tmp_v_addr, 0, size); rx_blocks->block_virt_addr = tmp_v_addr; rx_blocks->block_dma_addr = tmp_p_addr; @@ -647,6 +674,8 @@ static int init_shared_mem(struct s2io_nic *nic) GFP_KERNEL); if (!rx_blocks->rxds) return -ENOMEM; + mem_allocated += + (sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]); for (l=0; lrxd_mode];l++) { rx_blocks->rxds[l].virt_addr = rx_blocks->block_virt_addr + @@ -689,6 +718,7 @@ static int init_shared_mem(struct s2io_nic *nic) GFP_KERNEL); if (!mac_control->rings[i].ba) return -ENOMEM; + mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt); for (j = 0; j < blk_cnt; j++) { int k = 0; mac_control->rings[i].ba[j] = @@ -697,6 +727,8 @@ static int init_shared_mem(struct s2io_nic *nic) GFP_KERNEL); if (!mac_control->rings[i].ba[j]) return -ENOMEM; + mem_allocated += (sizeof(struct buffAdd) * \ + (rxd_count[nic->rxd_mode] + 1)); while (k != rxd_count[nic->rxd_mode]) { ba = &mac_control->rings[i].ba[j][k]; @@ -704,6 +736,8 @@ static int init_shared_mem(struct s2io_nic *nic) (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); if (!ba->ba_0_org) return -ENOMEM; + mem_allocated += + (BUF0_LEN + ALIGN_SIZE); tmp = (unsigned long)ba->ba_0_org; tmp += ALIGN_SIZE; tmp &= ~((unsigned long) ALIGN_SIZE); @@ -713,6 +747,8 @@ static int init_shared_mem(struct s2io_nic *nic) (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); if (!ba->ba_1_org) return -ENOMEM; + mem_allocated + += (BUF1_LEN + ALIGN_SIZE); tmp = (unsigned long) ba->ba_1_org; tmp += ALIGN_SIZE; tmp &= ~((unsigned long) ALIGN_SIZE); @@ -736,6 +772,7 @@ static int init_shared_mem(struct s2io_nic *nic) */ return -ENOMEM; } + mem_allocated += size; mac_control->stats_mem_sz = size; tmp_v_addr = mac_control->stats_mem; @@ -743,7 +780,7 @@ static int init_shared_mem(struct s2io_nic *nic) memset(tmp_v_addr, 0, size); DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, (unsigned long long) tmp_p_addr); - + mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; return SUCCESS; } @@ -757,12 +794,14 @@ static int init_shared_mem(struct s2io_nic *nic) static void free_shared_mem(struct s2io_nic *nic) { int i, j, blk_cnt, size; + u32 ufo_size = 0; void *tmp_v_addr; dma_addr_t tmp_p_addr; struct mac_info *mac_control; struct config_param *config; int lst_size, lst_per_page; struct net_device *dev = nic->dev; + int page_num = 0; if (!nic) return; @@ -774,8 +813,9 @@ static void free_shared_mem(struct s2io_nic *nic) lst_per_page = PAGE_SIZE / lst_size; for (i = 0; i < config->tx_fifo_num; i++) { - int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, - lst_per_page); + ufo_size += config->tx_cfg[i].fifo_len; + page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, + lst_per_page); for (j = 0; j < page_num; j++) { int mem_blks = (j * lst_per_page); if (!mac_control->fifos[i].list_info) @@ -790,6 +830,8 @@ static void free_shared_mem(struct s2io_nic *nic) mac_control->fifos[i]. list_info[mem_blks]. list_phy_addr); + nic->mac_control.stats_info->sw_stat.mem_freed + += PAGE_SIZE; } /* If we got a zero DMA address during allocation, * free the page now @@ -803,8 +845,12 @@ static void free_shared_mem(struct s2io_nic *nic) dev->name); DBG_PRINT(INIT_DBG, "Virtual address %p\n", mac_control->zerodma_virt_addr); + nic->mac_control.stats_info->sw_stat.mem_freed + += PAGE_SIZE; } kfree(mac_control->fifos[i].list_info); + nic->mac_control.stats_info->sw_stat.mem_freed += + (nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold)); } size = SIZE_OF_BLOCK; @@ -819,7 +865,10 @@ static void free_shared_mem(struct s2io_nic *nic) break; pci_free_consistent(nic->pdev, size, tmp_v_addr, tmp_p_addr); + nic->mac_control.stats_info->sw_stat.mem_freed += size; kfree(mac_control->rings[i].rx_blocks[j].rxds); + nic->mac_control.stats_info->sw_stat.mem_freed += + ( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]); } } @@ -836,12 +885,20 @@ static void free_shared_mem(struct s2io_nic *nic) struct buffAdd *ba = &mac_control->rings[i].ba[j][k]; kfree(ba->ba_0_org); + nic->mac_control.stats_info->sw_stat.\ + mem_freed += (BUF0_LEN + ALIGN_SIZE); kfree(ba->ba_1_org); + nic->mac_control.stats_info->sw_stat.\ + mem_freed += (BUF1_LEN + ALIGN_SIZE); k++; } kfree(mac_control->rings[i].ba[j]); + nic->mac_control.stats_info->sw_stat.mem_freed += (sizeof(struct buffAdd) * + (rxd_count[nic->rxd_mode] + 1)); } kfree(mac_control->rings[i].ba); + nic->mac_control.stats_info->sw_stat.mem_freed += + (sizeof(struct buffAdd *) * blk_cnt); } } @@ -850,9 +907,14 @@ static void free_shared_mem(struct s2io_nic *nic) mac_control->stats_mem_sz, mac_control->stats_mem, mac_control->stats_mem_phy); + nic->mac_control.stats_info->sw_stat.mem_freed += + mac_control->stats_mem_sz; } - if (nic->ufo_in_band_v) + if (nic->ufo_in_band_v) { kfree(nic->ufo_in_band_v); + nic->mac_control.stats_info->sw_stat.mem_freed + += (ufo_size * sizeof(u64)); + } } /** @@ -2122,10 +2184,12 @@ static void free_tx_buffers(struct s2io_nic *nic) for (i = 0; i < config->tx_fifo_num; i++) { for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { - txdp = (struct TxD *) mac_control->fifos[i].list_info[j]. - list_virt_addr; + txdp = (struct TxD *) \ + mac_control->fifos[i].list_info[j].list_virt_addr; skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); if (skb) { + nic->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; dev_kfree_skb(skb); cnt++; } @@ -2186,11 +2250,14 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \ /* skb_shinfo(skb)->frag_list will have L4 data payload */ skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); if (skb_shinfo(skb)->frag_list == NULL) { + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name); return -ENOMEM ; } frag_list = skb_shinfo(skb)->frag_list; skb->truesize += frag_list->truesize; + nic->mac_control.stats_info->sw_stat.mem_allocated + += frag_list->truesize; frag_list->next = NULL; tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1); frag_list->data = tmp; @@ -2319,8 +2386,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) wmb(); first_rxdp->Control_1 |= RXD_OWN_XENA; } + nic->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM ; } + nic->mac_control.stats_info->sw_stat.mem_allocated + += skb->truesize; if (nic->rxd_mode == RXD_MODE_1) { /* 1 buffer mode - normal operation mode */ memset(rxdp, 0, sizeof(struct RxD1)); @@ -2328,7 +2399,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); + rxdp->Control_2 = + SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); } else if (nic->rxd_mode >= RXD_MODE_3A) { /* @@ -2342,7 +2414,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) * payload */ - /* save the buffer pointers to avoid frequent dma mapping */ + /* save buffer pointers to avoid frequent dma mapping */ Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr; Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr; memset(rxdp, 0, sizeof(struct RxD3)); @@ -2364,7 +2436,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) PCI_DMA_FROMDEVICE); else pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, + (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { @@ -2391,6 +2463,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) } else { /* 3 buffer mode */ if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) { + nic->mac_control.stats_info->sw_stat.\ + mem_freed += skb->truesize; dev_kfree_skb_irq(skb); if (first_rxdp) { wmb(); @@ -2491,6 +2565,7 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) PCI_DMA_FROMDEVICE); memset(rxdp, 0, sizeof(struct RxD3)); } + sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[ring_no]); } @@ -2820,13 +2895,35 @@ static void tx_intr_handler(struct fifo_info *fifo_data) nic->mac_control.stats_info->sw_stat. parity_err_cnt++; } - if ((err >> 48) == 0xA) { - DBG_PRINT(TX_DBG, "TxD returned due \ - to loss of link\n"); - } - else { - DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err); - } + + /* update t_code statistics */ + err >>= 48; + switch(err) { + case 2: + nic->mac_control.stats_info->sw_stat. + tx_buf_abort_cnt++; + break; + + case 3: + nic->mac_control.stats_info->sw_stat. + tx_desc_abort_cnt++; + break; + + case 7: + nic->mac_control.stats_info->sw_stat. + tx_parity_err_cnt++; + break; + + case 10: + nic->mac_control.stats_info->sw_stat. + tx_link_loss_cnt++; + break; + + case 15: + nic->mac_control.stats_info->sw_stat. + tx_list_proc_err_cnt++; + break; + } } skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset); @@ -2839,6 +2936,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) /* Updating the statistics block */ nic->stats.tx_bytes += skb->len; + nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; dev_kfree_skb_irq(skb); get_info.offset++; @@ -3314,7 +3412,9 @@ static void s2io_reset(struct s2io_nic * sp) u16 subid, pci_cmd; int i; u16 val16; - unsigned long long reset_cnt = 0; + unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt; + unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt; + DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n", __FUNCTION__, sp->dev->name); @@ -3380,11 +3480,26 @@ static void s2io_reset(struct s2io_nic * sp) /* Reset device statistics maintained by OS */ memset(&sp->stats, 0, sizeof (struct net_device_stats)); - /* save reset count */ + + up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt; + down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt; + up_time = sp->mac_control.stats_info->sw_stat.link_up_time; + down_time = sp->mac_control.stats_info->sw_stat.link_down_time; reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt; + mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated; + mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed; + watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt; + /* save link up/down time/cnt, reset/memory/watchdog cnt */ memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block)); - /* restore reset count */ + /* restore link up/down time/cnt, reset/memory/watchdog cnt */ + sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt; + sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt; + sp->mac_control.stats_info->sw_stat.link_up_time = up_time; + sp->mac_control.stats_info->sw_stat.link_down_time = down_time; sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt; + sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt; + sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt; + sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt; /* SXE-002: Configure link and activity LED to turn it off */ subid = sp->pdev->subsystem_device; @@ -3672,19 +3787,29 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry), GFP_KERNEL); if (nic->entries == NULL) { - DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__); + DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ + __FUNCTION__); + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; return -ENOMEM; } - memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + nic->mac_control.stats_info->sw_stat.mem_allocated + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); nic->s2io_entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry), GFP_KERNEL); if (nic->s2io_entries == NULL) { - DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__); + DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", + __FUNCTION__); + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; kfree(nic->entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); return -ENOMEM; } + nic->mac_control.stats_info->sw_stat.mem_allocated + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); memset(nic->s2io_entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); @@ -3708,7 +3833,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) rx_mat = readq(&bar0->rx_mat); for (j=0; jconfig.rx_ring_num; j++, msix_indx++) { rx_mat |= RX_MAT_SET(j, msix_indx); - nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; + nic->s2io_entries[msix_indx].arg + = &nic->mac_control.rings[j]; nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; nic->s2io_entries[msix_indx].in_use = MSIX_FLG; } @@ -3717,7 +3843,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) tx_mat = readq(&bar0->tx_mat0_n[7]); for (j=0; jconfig.rx_ring_num; j++, msix_indx++) { tx_mat |= TX_MAT_SET(i, msix_indx); - nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; + nic->s2io_entries[msix_indx].arg + = &nic->mac_control.rings[j]; nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; nic->s2io_entries[msix_indx].in_use = MSIX_FLG; } @@ -3734,7 +3861,11 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) if (ret) { DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); kfree(nic->entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); kfree(nic->s2io_entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); nic->entries = NULL; nic->s2io_entries = NULL; nic->avail_msix_vectors = 0; @@ -3802,10 +3933,16 @@ static int s2io_open(struct net_device *dev) hw_init_failed: if (sp->intr_type == MSI_X) { - if (sp->entries) + if (sp->entries) { kfree(sp->entries); - if (sp->s2io_entries) + sp->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + } + if (sp->s2io_entries) { kfree(sp->s2io_entries); + sp->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); + } } return err; } @@ -3866,6 +4003,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) config = &sp->config; DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name); + + if (unlikely(skb->len <= 0)) { + DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); + dev_kfree_skb_any(skb); + return 0; +} + spin_lock_irqsave(&sp->tx_lock, flags); if (atomic_read(&sp->card_state) == CARD_DOWN) { DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", @@ -3876,7 +4020,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } queue = 0; - /* Get Fifo number to Transmit based on vlan priority */ if (sp->vlgrp && vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); @@ -3900,14 +4043,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - /* A buffer with no data will be dropped */ - if (!skb->len) { - DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); - dev_kfree_skb(skb); - spin_unlock_irqrestore(&sp->tx_lock, flags); - return 0; - } - offload_type = s2io_offload_type(skb); if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { txdp->Control_1 |= TXD_TCP_LSO_EN; @@ -4003,7 +4138,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) put_off, get_off); netif_stop_queue(dev); } - + mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; dev->trans_start = jiffies; spin_unlock_irqrestore(&sp->tx_lock, flags); @@ -4775,6 +4910,40 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) return 0; } +static void s2io_ethtool_gringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct s2io_nic *sp = dev->priv; + int i,tx_desc_count=0,rx_desc_count=0; + + if (sp->rxd_mode == RXD_MODE_1) + ering->rx_max_pending = MAX_RX_DESC_1; + else if (sp->rxd_mode == RXD_MODE_3B) + ering->rx_max_pending = MAX_RX_DESC_2; + else if (sp->rxd_mode == RXD_MODE_3A) + ering->rx_max_pending = MAX_RX_DESC_3; + + ering->tx_max_pending = MAX_TX_DESC; + for (i = 0 ; i < sp->config.tx_fifo_num ; i++) { + tx_desc_count += sp->config.tx_cfg[i].fifo_len; + } + DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds); + ering->tx_pending = tx_desc_count; + rx_desc_count = 0; + for (i = 0 ; i < sp->config.rx_ring_num ; i++) { + rx_desc_count += sp->config.rx_cfg[i].num_rxd; + } + ering->rx_pending = rx_desc_count; + + ering->rx_mini_max_pending = 0; + ering->rx_mini_pending = 0; + if(sp->rxd_mode == RXD_MODE_1) + ering->rx_jumbo_max_pending = MAX_RX_DESC_1; + else if (sp->rxd_mode == RXD_MODE_3B) + ering->rx_jumbo_max_pending = MAX_RX_DESC_2; + ering->rx_jumbo_pending = rx_desc_count; +} + /** * s2io_ethtool_getpause_data -Pause frame frame generation and reception. * @sp : private member of the device structure, which is a pointer to the @@ -4981,8 +5150,11 @@ static void s2io_vpd_read(struct s2io_nic *nic) strcpy(nic->serial_num, "NOT AVAILABLE"); vpd_data = kmalloc(256, GFP_KERNEL); - if (!vpd_data) + if (!vpd_data) { + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; return; + } + nic->mac_control.stats_info->sw_stat.mem_allocated += 256; for (i = 0; i < 256; i +=4 ) { pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); @@ -5022,6 +5194,7 @@ static void s2io_vpd_read(struct s2io_nic *nic) memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); } kfree(vpd_data); + nic->mac_control.stats_info->sw_stat.mem_freed += 256; } /** @@ -5742,6 +5915,30 @@ static void s2io_get_ethtool_stats(struct net_device *dev, } else tmp_stats[i++] = 0; + tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt; + tmp_stats[i++] = stat_info->sw_stat.mem_allocated; + tmp_stats[i++] = stat_info->sw_stat.mem_freed; + tmp_stats[i++] = stat_info->sw_stat.link_up_cnt; + tmp_stats[i++] = stat_info->sw_stat.link_down_cnt; + tmp_stats[i++] = stat_info->sw_stat.link_up_time; + tmp_stats[i++] = stat_info->sw_stat.link_down_time; + + tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt; + + tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt; } static int s2io_ethtool_get_regs_len(struct net_device *dev) @@ -5854,6 +6051,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_eeprom_len = s2io_get_eeprom_len, .get_eeprom = s2io_ethtool_geeprom, .set_eeprom = s2io_ethtool_seeprom, + .get_ringparam = s2io_ethtool_gringparam, .get_pauseparam = s2io_ethtool_getpause_data, .set_pauseparam = s2io_ethtool_setpause_data, .get_rx_csum = s2io_ethtool_get_rx_csum, @@ -5962,7 +6160,7 @@ static void s2io_tasklet(unsigned long dev_addr) if (ret == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); - DBG_PRINT(ERR_DBG, "memory in tasklet\n"); + DBG_PRINT(INFO_DBG, "memory in tasklet\n"); break; } else if (ret == -EFILL) { DBG_PRINT(INFO_DBG, @@ -6077,9 +6275,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, *skb = dev_alloc_skb(size); if (!(*skb)) { DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); - DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n"); + DBG_PRINT(INFO_DBG, "memory to allocate "); + DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n"); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM ; } + sp->mac_control.stats_info->sw_stat.mem_allocated + += (*skb)->truesize; /* storing the mapped addr in a temp variable * such it will be used for next rxd whose * Host Control is NULL @@ -6099,10 +6302,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, } else { *skb = dev_alloc_skb(size); if (!(*skb)) { - DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n", - dev->name); + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); + DBG_PRINT(INFO_DBG, "memory to allocate "); + DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n"); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM; } + sp->mac_control.stats_info->sw_stat.mem_allocated + += (*skb)->truesize; ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, @@ -6126,10 +6334,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, } else { *skb = dev_alloc_skb(size); if (!(*skb)) { - DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n", - dev->name); + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); + DBG_PRINT(INFO_DBG, "memory to allocate "); + DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n"); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM; } + sp->mac_control.stats_info->sw_stat.mem_allocated + += (*skb)->truesize; ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 = pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -6147,10 +6360,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, if (skb_shinfo(*skb)->frag_list == NULL) { DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ failed\n ", dev->name); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM ; } frag_list = skb_shinfo(*skb)->frag_list; frag_list->next = NULL; + sp->mac_control.stats_info->sw_stat.mem_allocated + += frag_list->truesize; /* * Buffer-2 receives L4 data payload */ @@ -6566,6 +6783,7 @@ static void s2io_tx_watchdog(struct net_device *dev) struct s2io_nic *sp = dev->priv; if (netif_carrier_ok(dev)) { + sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++; schedule_work(&sp->rst_timer_task); sp->mac_control.stats_info->sw_stat.soft_reset_cnt++; } @@ -6606,7 +6824,53 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) if (err & 0x1) { sp->mac_control.stats_info->sw_stat.parity_err_cnt++; } + err >>= 48; + switch(err) { + case 1: + sp->mac_control.stats_info->sw_stat. + rx_parity_err_cnt++; + break; + case 2: + sp->mac_control.stats_info->sw_stat. + rx_abort_cnt++; + break; + + case 3: + sp->mac_control.stats_info->sw_stat. + rx_parity_abort_cnt++; + break; + + case 4: + sp->mac_control.stats_info->sw_stat. + rx_rda_fail_cnt++; + break; + + case 5: + sp->mac_control.stats_info->sw_stat. + rx_unkn_prot_cnt++; + break; + + case 6: + sp->mac_control.stats_info->sw_stat. + rx_fcs_err_cnt++; + break; + + case 7: + sp->mac_control.stats_info->sw_stat. + rx_buf_size_err_cnt++; + break; + + case 8: + sp->mac_control.stats_info->sw_stat. + rx_rxd_corrupt_cnt++; + break; + + case 15: + sp->mac_control.stats_info->sw_stat. + rx_unkn_err_cnt++; + break; + } /* * Drop the packet if bad transfer code. Exception being * 0x5, which could be due to unsupported IPv6 extension header. @@ -6614,10 +6878,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) * Note that in this case, since checksum will be incorrect, * stack will validate the same. */ - if (err && ((err >> 48) != 0x5)) { + if (err != 0x5) { DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", dev->name, err); sp->stats.rx_crc_errors++; + sp->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[ring_no]); rxdp->Host_Control = 0; @@ -6627,7 +6893,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) /* Updating statistics */ rxdp->Host_Control = 0; - sp->stats.rx_packets++; if (sp->rxd_mode == RXD_MODE_1) { int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); @@ -6731,7 +6996,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) } else { skb->ip_summed = CHECKSUM_NONE; } - + sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; if (!sp->lro) { skb->protocol = eth_type_trans(skb, dev); if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) && @@ -6780,12 +7045,21 @@ static void s2io_link(struct s2io_nic * sp, int link) if (link == LINK_DOWN) { DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); netif_carrier_off(dev); + if(sp->mac_control.stats_info->sw_stat.link_up_cnt) + sp->mac_control.stats_info->sw_stat.link_up_time = + jiffies - sp->start_time; + sp->mac_control.stats_info->sw_stat.link_down_cnt++; } else { DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name); + if (sp->mac_control.stats_info->sw_stat.link_down_cnt) + sp->mac_control.stats_info->sw_stat.link_down_time = + jiffies - sp->start_time; + sp->mac_control.stats_info->sw_stat.link_up_cnt++; netif_carrier_on(dev); } } sp->last_link_state = link; + sp->start_time = jiffies; } /** diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index a656d18b33df..54baa0b8ec7c 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -95,6 +95,32 @@ struct swStat { unsigned long long flush_max_pkts; unsigned long long sum_avg_pkts_aggregated; unsigned long long num_aggregations; + /* Other statistics */ + unsigned long long mem_alloc_fail_cnt; + unsigned long long watchdog_timer_cnt; + unsigned long long mem_allocated; + unsigned long long mem_freed; + unsigned long long link_up_cnt; + unsigned long long link_down_cnt; + unsigned long long link_up_time; + unsigned long long link_down_time; + + /* Transfer Code statistics */ + unsigned long long tx_buf_abort_cnt; + unsigned long long tx_desc_abort_cnt; + unsigned long long tx_parity_err_cnt; + unsigned long long tx_link_loss_cnt; + unsigned long long tx_list_proc_err_cnt; + + unsigned long long rx_parity_err_cnt; + unsigned long long rx_abort_cnt; + unsigned long long rx_parity_abort_cnt; + unsigned long long rx_rda_fail_cnt; + unsigned long long rx_unkn_prot_cnt; + unsigned long long rx_fcs_err_cnt; + unsigned long long rx_buf_size_err_cnt; + unsigned long long rx_rxd_corrupt_cnt; + unsigned long long rx_unkn_err_cnt; }; /* Xpak releated alarm and warnings */ @@ -308,6 +334,11 @@ struct stat_block { #define MAX_TX_FIFOS 8 #define MAX_RX_RINGS 8 +#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) +#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) +#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) +#define MAX_TX_DESC (MAX_AVAILABLE_TXDS) + /* FIFO mappings for all possible number of fifos configured */ static int fifo_map[][MAX_TX_FIFOS] = { {0, 0, 0, 0, 0, 0, 0, 0}, @@ -819,6 +850,7 @@ struct s2io_nic { #define LINK_UP 2 int task_flag; + unsigned long long start_time; #define CARD_DOWN 1 #define CARD_UP 2 atomic_t card_state; diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index e0489578945d..776692946562 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -3802,6 +3802,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) struct skge_hw *hw = pci_get_drvdata(pdev); int i, err, wol = 0; + if (!hw) + return 0; + err = pci_save_state(pdev); if (err) return err; @@ -3830,6 +3833,9 @@ static int skge_resume(struct pci_dev *pdev) struct skge_hw *hw = pci_get_drvdata(pdev); int i, err; + if (!hw) + return 0; + err = pci_set_power_state(pdev, PCI_D0); if (err) goto out; @@ -3868,6 +3874,9 @@ static void skge_shutdown(struct pci_dev *pdev) struct skge_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; + if (!hw) + return; + for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; struct skge_port *skge = netdev_priv(dev); diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index a307310f13f5..104e20456e6f 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -130,7 +131,7 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ +// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ { 0 } }; @@ -150,6 +151,8 @@ static const char *yukon2_name[] = { "FE", /* 0xb7 */ }; +static int dmi_blacklisted; + /* Access to external PHY */ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) { @@ -2531,6 +2534,17 @@ static int __devinit sky2_init(struct sky2_hw *hw) return -EOPNOTSUPP; } + + /* Some Gigabyte motherboards have 88e8056 but cause problems + * There is some unresolved hardware related problem that causes + * descriptor errors and receive data corruption. + */ + if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) { + dev_err(&hw->pdev->dev, + "88E8056 on this motherboard not supported\n"); + return -EOPNOTSUPP; + } + hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); hw->ports = 1; t8 = sky2_read8(hw, B2_Y2_HW_RES); @@ -3578,17 +3592,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out; } - /* Some Gigabyte motherboards have 88e8056 but cause problems - * There is some unresolved hardware related problem that causes - * descriptor errors and receive data corruption. - */ - if (pdev->vendor == PCI_VENDOR_ID_MARVELL && - pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) { - dev_err(&pdev->dev, - "88E8056 on Gigabyte motherboards not supported\n"); - goto err_out_disable; - } - err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(&pdev->dev, "cannot obtain PCI resources\n"); @@ -3732,6 +3735,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, err_out_disable: pci_disable_device(pdev); err_out: + pci_set_drvdata(pdev, NULL); return err; } @@ -3784,6 +3788,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) struct sky2_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; + if (!hw) + return 0; + del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); @@ -3815,6 +3822,9 @@ static int sky2_resume(struct pci_dev *pdev) struct sky2_hw *hw = pci_get_drvdata(pdev); int i, err; + if (!hw) + return 0; + err = pci_set_power_state(pdev, PCI_D0); if (err) goto out; @@ -3861,6 +3871,9 @@ static void sky2_shutdown(struct pci_dev *pdev) struct sky2_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; + if (!hw) + return; + del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); @@ -3897,8 +3910,24 @@ static struct pci_driver sky2_driver = { .shutdown = sky2_shutdown, }; +static struct dmi_system_id __initdata broken_dmi_table[] = { + { + .ident = "Gigabyte 965P-S3", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."), + DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"), + + }, + }, + { } +}; + static int __init sky2_init_module(void) { + /* Look for sick motherboards */ + if (dmi_check_system(broken_dmi_table)) + dmi_blacklisted = 1; + return pci_register_driver(&sky2_driver); } diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index c15e97253ede..108adbf5b5eb 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -175,12 +175,10 @@ spider_net_setup_aneg(struct spider_net_card *card) { struct mii_phy *phy = &card->phy; u32 advertise = 0; - u16 bmcr, bmsr, stat1000, estat; + u16 bmsr, estat; - bmcr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR); - bmsr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR); - stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000); - estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS); + bmsr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR); + estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS); if (bmsr & BMSR_10HALF) advertise |= ADVERTISED_10baseT_Half; diff --git a/trunk/drivers/net/wan/Kconfig b/trunk/drivers/net/wan/Kconfig index 8897f538a7c7..4fc8681bc110 100644 --- a/trunk/drivers/net/wan/Kconfig +++ b/trunk/drivers/net/wan/Kconfig @@ -2,10 +2,7 @@ # wan devices configuration # -menu "Wan interfaces" - depends on NETDEVICES - -config WAN +menuconfig WAN bool "Wan interfaces support" ---help--- Wide Area Networks (WANs), such as X.25, Frame Relay and leased @@ -23,10 +20,12 @@ config WAN If unsure, say N. +if WAN + # There is no way to detect a comtrol sv11 - force it modular for now. config HOSTESS_SV11 tristate "Comtrol Hostess SV-11 support" - depends on WAN && ISA && m && ISA_DMA_API && INET + depends on ISA && m && ISA_DMA_API && INET help Driver for Comtrol Hostess SV-11 network card which operates on low speed synchronous serial links at up to @@ -38,7 +37,7 @@ config HOSTESS_SV11 # The COSA/SRP driver has not been tested as non-modular yet. config COSA tristate "COSA/SRP sync serial boards support" - depends on WAN && ISA && m && ISA_DMA_API + depends on ISA && m && ISA_DMA_API ---help--- Driver for COSA and SRP synchronous serial boards. @@ -62,7 +61,7 @@ config COSA # config LANMEDIA tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards" - depends on WAN && PCI + depends on PCI ---help--- Driver for the following Lan Media family of serial boards: @@ -89,7 +88,7 @@ config LANMEDIA # There is no way to detect a Sealevel board. Force it modular config SEALEVEL_4021 tristate "Sealevel Systems 4021 support" - depends on WAN && ISA && m && ISA_DMA_API && INET + depends on ISA && m && ISA_DMA_API && INET help This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. @@ -99,7 +98,6 @@ config SEALEVEL_4021 # Generic HDLC config HDLC tristate "Generic HDLC layer" - depends on WAN help Say Y to this option if your Linux box contains a WAN (Wide Area Network) card supported by this driver and you are planning to @@ -167,7 +165,7 @@ config HDLC_X25 If unsure, say N. comment "X.25/LAPB support is disabled" - depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y + depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y config PCI200SYN tristate "Goramo PCI200SYN support" @@ -230,10 +228,10 @@ config PC300_MLPPP Multilink PPP over the PC300 synchronous communication boards. comment "Cyclades-PC300 MLPPP support is disabled." - depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) comment "Refer to the file README.mlppp, provided by PC300 package." - depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) config PC300TOO tristate "Cyclades PC300 RSV/X21 alternative support" @@ -338,7 +336,6 @@ config DSCC4_PCI_RST config DLCI tristate "Frame Relay DLCI support" - depends on WAN ---help--- Support for the Frame Relay protocol. @@ -385,7 +382,7 @@ config SDLA # Wan router core. config WAN_ROUTER_DRIVERS tristate "WAN router drivers" - depends on WAN && WAN_ROUTER + depends on WAN_ROUTER ---help--- Connect LAN to WAN via Linux box. @@ -440,7 +437,7 @@ config CYCLOMX_X25 # X.25 network drivers config LAPBETHER tristate "LAPB over Ethernet driver (EXPERIMENTAL)" - depends on WAN && LAPB && X25 + depends on LAPB && X25 ---help--- Driver for a pseudo device (typically called /dev/lapb0) which allows you to open an LAPB point-to-point connection to some other computer @@ -456,7 +453,7 @@ config LAPBETHER config X25_ASY tristate "X.25 async driver (EXPERIMENTAL)" - depends on WAN && LAPB && X25 + depends on LAPB && X25 ---help--- Send and receive X.25 frames over regular asynchronous serial lines such as telephone lines equipped with ordinary modems. @@ -471,7 +468,7 @@ config X25_ASY config SBNI tristate "Granch SBNI12 Leased Line adapter support" - depends on WAN && X86 + depends on X86 ---help--- Driver for ISA SBNI12-xx cards which are low cost alternatives to leased line modems. @@ -497,5 +494,4 @@ config SBNI_MULTILINE If unsure, say N. -endmenu - +endif # WAN diff --git a/trunk/drivers/net/wireless/libertas/Makefile b/trunk/drivers/net/wireless/libertas/Makefile index 19c935071d8e..56a8ea1fbf04 100644 --- a/trunk/drivers/net/wireless/libertas/Makefile +++ b/trunk/drivers/net/wireless/libertas/Makefile @@ -1,5 +1,3 @@ -# EXTRA_CFLAGS += -Wpacked - usb8xxx-objs := main.o fw.o wext.o \ rx.o tx.o cmd.o \ cmdresp.o scan.o \ @@ -7,13 +5,6 @@ usb8xxx-objs := main.o fw.o wext.o \ ioctl.o debugfs.o \ ethtool.o assoc.o -ifeq ($(CONFIG_LIBERTAS_USB_DEBUG), y) -EXTRA_CFLAGS += -DDEBUG -DPROC_DEBUG -endif - - -# This is needed to support the newer boot2 bootloader (v >= 3104) -EXTRA_CFLAGS += -DSUPPORT_BOOT_COMMAND usb8xxx-objs += if_bootcmd.o usb8xxx-objs += if_usb.o diff --git a/trunk/drivers/net/wireless/libertas/README b/trunk/drivers/net/wireless/libertas/README index 688da4c784b1..378577200b56 100644 --- a/trunk/drivers/net/wireless/libertas/README +++ b/trunk/drivers/net/wireless/libertas/README @@ -40,64 +40,11 @@ NAME SYNOPSIS iwpriv [sub-command] ... - iwpriv ethX version - iwpriv ethX scantype [sub-command] - iwpriv ethX getSNR - iwpriv ethX getNF - iwpriv ethX getRSSI - iwpriv ethX setrxant - iwpriv ethX getrxant - iwpriv ethX settxant - iwpriv ethX gettxant - iwpriv ethX authalgs - iwpriv ethX pre-TBTT - iwpriv ethX 8021xauthalgs - iwpriv ethX encryptionmode iwpriv ethX setregioncode iwpriv ethX getregioncode - iwpriv ethX setbcnavg - iwpriv ethX getbcnavg - iwpriv ethX setdataavg - iwpriv ethX setlisteninter - iwpriv ethX getlisteninter - iwpriv ethX setmultipledtim - iwpriv ethX getmultipledtim - iwpriv ethX atimwindow - iwpriv ethX deauth - iwpriv ethX adhocstop - iwpriv ethX radioon - iwpriv ethX radiooff - iwpriv ethX reasso-on - iwpriv ethX reasso-off - iwpriv ethX scanmode [sub-command] - iwpriv ethX setwpaie - iwpriv ethX wlanidle-off - iwpriv ethX wlanidle-on - iwpriv ethX getcis - iwpriv ethX getlog - iwpriv ethX getadhocstatus - iwpriv ethX adhocgrate - -Version 4 Command: - iwpriv ethX inactvityto - iwpriv ethX sleeppd - iwpriv ethX enable11d - iwpriv ethX tpccfg - iwpriv ethX powercfg - iwpriv ethX setafc - iwpriv ethX getafc Version 5 Command: iwpriv ethX ledgpio - iwpriv ethX scanprobes - iwpriv ethX lolisteninter - iwpriv ethX rateadapt - iwpriv ethX txcontrol - iwpriv ethX psnullinterval - iwpriv ethX prescan - iwpriv ethX getrxinfo - iwpriv ethX gettxrate - iwpriv ethX beaconinterval BT Commands: The blinding table (BT) contains a list of mac addresses that should be @@ -150,114 +97,6 @@ DESCRIPTION The ethX parameter specifies the network device that is to be used to perform this command on. it could be eth0, eth1 etc. -version - This is used to get the current version of the driver and the firmware. - -scantype - This command is used to set the scan type to be used by the driver in - the scan command. This setting will not be used while performing a scan - for a specific SSID, as it is always done with scan type being active. - - where the sub-commands are: - - active -- to set the scan type to active - passive -- to set the scan type to passive - get -- to get the scan type set in the driver - -getSNR - This command gets the average and non average value of Signal to Noise - Ratio of Beacon and Data. - - where value is:- - 0 -- Beacon non-average. - 1 -- Beacon average. - 2 -- Data non-average. - 3 -- Data average. - - If no value is given, all four values are returned in the order mentioned - above. - - Note: This command is available only when STA is connected. - -getRSSI - This command gets the average and non average value os Receive Signal - Strength of Beacon and Data. - - where value is:- - 0 -- Beacon non-average. - 1 -- Beacon average. - 2 -- Data non-average. - 3 -- Data average. - - Note: This command is available only when STA is connected. - -getNF - This command gets the average and non average value of Noise Floor of - Beacon and Data. - - where value is:- - 0 -- Beacon non-average. - 1 -- Beacon average. - 2 -- Data non-average. - 3 -- Data average. - - Note: This command is available only when STA is connected. - -setrxant - This command is used to set the mode for Rx antenna. - - The options that can be sent are:- - 1 -- Antenna 1. - 2 -- Antenna 2. - 0xFFFF -- Diversity. - - Usage: - iwpriv ethX setrxant 0x01: select Antenna 1. - -getrxant - This command is used to get the mode for Rx antenna. - - -settxant - This command is used to set the mode for Tx antenna. - The options that can be sent are:- - 1 -- Antenna 1. - 2 -- Antenna 2. - 0xFFFF -- Diversity. - Usage: - iwpriv ethX settxant 0x01: select Antenna 1. - -gettxant - This command is used to get the mode for Tx antenna. - -authalgs - This command is used by the WPA supplicant to set the authentication - algorithms in the station. - -8021xauthalgs - This command is used by the WPA supplicant to set the 8021.x authentication algorithm type - station. - - where values can be:- - 1 -- None - 2 -- LEAP - 4 -- TLS - 8 -- TTLs - 16 -- MD5 - - -encryptionmode - This command is used by the WPA supplicant to set the encryption algorithm. - - where values can be:- - 0 -- NONE - 1 -- WEP40 - 2 -- TKIP - 3 -- CCMP - 4 -- WEP104 - -pre-TBTT - This command is used to set pre-TBTT time period where value is in microseconds. - setregioncode This command is used to set the region code in the station. where value is 'region code' for various regions like @@ -270,114 +109,6 @@ getregioncode This command is used to get the region code information set in the station. -setbcnavg - Set the weighting factor for calculating RSSI. - -getbcnavg - Get weighting factor for calculating RSSI. - -setdataavg - Set the weighting factor for calculating SNR. - -setlisteninter - This command is used to set the listen interval in the - station. - - where the value ranges between 1 - 255 - -getlisteninter - This command is used to get the listen interval value set in the - station. - -setmultipledtim - This command is used to set the multiple dtim value in the - station. - where the value is 1,2,3,4,5,0xfffe - 0xfffe means the firmware will use listen interval in association - command for waking up - -getmultipledtim - This command is used to get the multiple dtim value set in the station. - -atimwindow - This command is used to set the atim value in the - station. - - where the value ranges between 0 - 50 - -deauth - This command is used to send the de-authentication to the AP with which - the station is associated. This command is valid only when - station is in Infrastructure mode. - - Note: This command is available only when STA is connected. - -adhocstop - This command is used to stop beacon transmission from the station and - go into idle state in ad-hoc mode. - - Note: This command is available only when STA is connected. - -radioon - This command is used to turn on the RF antenna. - -radiooff - This command is sued to turn off the RF antenna. - -scanmode - This command is used to set the station to scan for either IBSS - networks or BSS networks or both BSS and IBSS networks. This - command can be used with sub commands, - - where the value for - bss -- Scan All the BSS networks. - ibss -- Scan All the IBSS networks. - any -- Scan both BSS and IBSS networks. - - - -setwpaie - This command is used by WPA supplicant to send the WPA-IE to the driver. - -wlanidle-off - This command is used to get into idle state. - - Note: This command is available only when STA is connected. - -wlanidle-on - This command is used to get off the idle state. - - Note: This command is available only when STA is connected. - - -getlog - This command is used to get the 802.11 statistics available in the - station. - - Note: This command is available only when STA is connected. - -getadhocstatus - This command is used to get the ad-hoc Network Status. - - The various status codes are: - AdhocStarted - AdhocJoined - AdhocIdle - InfraMode - AutoUnknownMode - - Note: This command is available only when STA is connected. - -adhocgrate - This command is used to enable(1) g_rate, Disable(0) g_rate - and request(2) the status which g_rate is disabled/enabled, - for Ad-hoc creator. - - where value is:- - 0 -- Disabled - 1 -- Enabled - 2 -- Get - ledgpio This command is used to set/get LEDs. @@ -400,253 +131,6 @@ ledgpio Note: LED0 is invalid Note: Maximum Number of LEDs are 16. -inactivityto - This command is used by the host to set/get the inactivity timeout value, - which specifies when WLAN device is put to sleep. - - Usage: - iwpriv ethX inactivityto [] - - where the parameter are: - timeout: timeout value in milliseconds. - - Example: - iwpriv eth1 inactivityto - "get the timeout value" - - iwpriv eth1 inactivityto X - "set timeout value to X ms" - - -sleeppd - This command is used to configure the sleep period of the WLAN device. - - Usage: - iwpriv ethX sleeppd [] - - where the parameter are: - Period: sleep period in milliseconds. Range 10~60. - - Example: - iwpriv eth1 sleeppd 10 - "set period as 10 ms" - iwpriv eth1 sleeppd - "get the sleep period configuration" - -enable11d - This command is used to control 11d - where value is:- - 1 -- Enabled - 0 -- Disabled - 2 -- Get - - - - -tpccfg - Enables or disables automatic transmit power control. - - The first parameter turns this feature on (1) or off (0). When turning - on, the user must also supply four more parameters in the following - order: - -UseSNR (Use SNR (in addition to PER) for TPC algorithm), - -P0 (P0 power level for TPC), - -P1 (P1 power level for TPC), - -P2 (P2 power level for TPC). - - Usage: - iwpriv ethX tpccfg: Get current configuration - iwpriv ethX tpccfg 0: disable auto TPC - iwpriv ethX tpccfg 0x01 0x00 0x05 0x0a 0x0d: enable auto TPC; do not use SNR; - P0=0x05; P1=0x0a; P2=0x0d; - iwpriv ethX tpccfg 0x01 0x01 0x05 0x0a 0x0d: enable auto TPC; use SNR; - P0=0x05; P1=0x0a; P2=0x0d. - -powercfg - Enables or disables power adaptation. - - The first parameter turns this feature on (1) or off (0). When turning - on, the user must also supply three more parameters in the following - order: - -P0 (P0 power level for Power Adaptation), - -P1 (P1 power level for Power Adaptation), - -P2 (P2 power level for Power Adaptation). - - Usage: - iwpriv ethX powercfg: Get current configuration - iwpriv ethX powercfg 0: disable power adaptation - iwpriv ethX powercfg 1 0x0d 0x0f 0x12: enable power adaptation; - P0=0x0d; P1=0x0f; P2=0x12. - -getafc - This command returns automatic frequency control parameters. It returns - three integers: - -P0: automatic is on (1), or off (0), - -P1: current timing offset in PPM (part per million), and - -P2: current frequency offset in PPM. - -setafc - Set automatic frequency control options. - - The first parameter turns automatic on (1) or off (0). - The user must supply two more parameters in either case, in the following - order: - - When auto is on: - - -P0 (automatic adjustment frequency threshold in PPM), - -P1 (automatic adjustment period in beacon period), - - When auto is off: - - -P0 (manual adjustment timing offset in PPM), and - -P1 (manual adjustment frequency offset in PPM). - - Usage: - iwpriv ethX setafc 0 10 10: manual adjustment, both timing and frequcncy - offset are 10 PPM. - - iwpriv ethX setafc 1 10 10 enable afc, automatic adjustment, - frequency threshold 10 PPM, for every 10 beacon periods. - - - -scanprobes - This command sets number of probe requests per channel. - - Usage: - iwpriv ethX scanprobes 3 (set scan probes to 3) - iwpriv ethX scanprobes (get scan probes) - -lolisteninter - This command sets the value of listen interval. - - Usage: - iwpriv ethX lolisteninter 234 (set the lolisteninter to 234) - iwpriv ethX lolisteninter (get the lolisteninter value) - -rateadapt - This command sets the data rates bitmap. - Where - 0: Disable auto rate adapt - 1: Enable auto rate adapt - - - data rate bitmap - Bit Data rate - 0 1 Mbps - 1 2 Mbps - 2 5.5 Mbps - 3 11 Mbps - 4 Reserved - 5 6 Mbps - 6 9 Mbps - 7 12 Mbps - 8 18 Mbps - 9 24 Mbps - 10 36 Mbps - 11 48 Mbps - 12 54 Mbps - 12-15 Reserved - - Usage: - iwpriv ethX rateadapt - read the currect data rate setting - iwpriv ethX rateadapt 1 0x07 - enable auto data rate adapt and - data rates are 1Mbps, 2Mbsp and 5.5Mbps - - -txcontrol - This command is used to set the Tx rate, ack policy, and retry limit on a per packet basis. - - Where value is: - if bit[4] == 1: - bit[3:0] -- 0 1 2 3 4 5 6 7 8 9 10 11 12 13-16 - Data Rate(Mbps) -- 1 2 5.5 11 Rsv 6 9 12 18 24 36 48 54 Rsv - - bit[12:8] - if bit[12] == 1, bit[11:8] specifies the Tx retry limit. - - bit[14:13] specifies per packet ack policy: - bit[14:13] - 1 0 use immediate ack policy for this packet - 1 1 use no ack policy for this packet - 0 x use the per-packet ack policy setting - - Usage: - iwpriv ethX txcontrol 0x7513 - Use no-ack policy, 5 retires for Tx, 11Mbps rate - - - -psnullinterval - This command is used to set/request NULL package interval for Power Save - under infrastructure mode. - - where value is:- - -1 -- Disabled - n>0 -- Set interval as n (seconds) - -prescan - This command is used to enable (1)/disable(0) auto prescan before assoicate to the ap - - where value is:- - 0 -- Disabled - 1 -- Enabled - 2 -- Get - -getrxinfo - This command gets non average value of Signal to Noise Ratio of Data and rate index. - - The following table shows RateIndex and Rate - - RateIndex Data rate - 0 1 Mbps - 1 2 Mbps - 2 5.5 Mbps - 3 11 Mbps - 4 Reserved - 5 6 Mbps - 6 9 Mbps - 7 12 Mbps - 8 18 Mbps - 9 24 Mbps - 10 36 Mbps - 11 48 Mbps - 12 54 Mbps - 13-15 Reserved - -gettxrate - This command gets current Tx rate index of the first packet associated with Rate Adaptation. - - The following table shows RateIndex and Rate - - RateIndex Data rate - 0 1 Mbps - 1 2 Mbps - 2 5.5 Mbps - 3 11 Mbps - 4 Reserved - 5 6 Mbps - 6 9 Mbps - 7 12 Mbps - 8 18 Mbps - 9 24 Mbps - 10 36 Mbps - 11 48 Mbps - 12 54 Mbps - 13-15 Reserved - -bcninterval - This command is used to sets beacon interval in adhoc mode when an argument is given, and gets current adhoc - beacon interval when no argument is given. The valid beacon interval is between 20 - 1000, - default beacon interval is 100. - - Usage: - iwpriv ethX bcninterval 100 (set adhoc beacon interval to 100) - iwpriv ethX bcninterval (get adhoc beacon interval) - fwt_add This command is used to insert an entry into the FWT table. The list of parameters must follow the following structure: diff --git a/trunk/drivers/net/wireless/libertas/assoc.c b/trunk/drivers/net/wireless/libertas/assoc.c index b55c7f57aca8..c260bd1b3d46 100644 --- a/trunk/drivers/net/wireless/libertas/assoc.c +++ b/trunk/drivers/net/wireless/libertas/assoc.c @@ -23,13 +23,13 @@ static int assoc_helper_essid(wlan_private *priv, ENTER(); lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid); - if (assoc_req->mode == wlan802_11infrastructure) { + if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->prescan) { libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1); } i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, - NULL, wlan802_11infrastructure); + NULL, IW_MODE_INFRA); if (i >= 0) { lbs_pr_debug(1, "SSID found in scan list ... associating...\n"); @@ -44,7 +44,7 @@ static int assoc_helper_essid(wlan_private *priv, lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n", assoc_req->ssid.ssid); } - } else if (assoc_req->mode == wlan802_11ibss) { + } else if (assoc_req->mode == IW_MODE_ADHOC) { /* Scan for the network, do not save previous results. Stale * scan data will cause us to join a non-existant adhoc network */ @@ -52,7 +52,7 @@ static int assoc_helper_essid(wlan_private *priv, /* Search for the requested SSID in the scan table */ i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL, - wlan802_11ibss); + IW_MODE_ADHOC); if (i >= 0) { lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret); libertas_join_adhoc_network(priv, &adapter->scantable[i]); @@ -90,10 +90,10 @@ static int assoc_helper_bssid(wlan_private *priv, goto out; } - if (assoc_req->mode == wlan802_11infrastructure) { + if (assoc_req->mode == IW_MODE_INFRA) { ret = wlan_associate(priv, &adapter->scantable[i]); lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret); - } else if (assoc_req->mode == wlan802_11ibss) { + } else if (assoc_req->mode == IW_MODE_ADHOC) { libertas_join_adhoc_network(priv, &adapter->scantable[i]); } memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid, @@ -142,23 +142,23 @@ static int assoc_helper_mode(wlan_private *priv, ENTER(); - if (assoc_req->mode == adapter->inframode) { + if (assoc_req->mode == adapter->mode) { LEAVE(); return 0; } - if (assoc_req->mode == wlan802_11infrastructure) { + if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->psstate != PS_STATE_FULL_POWER) libertas_ps_wakeup(priv, cmd_option_waitforrsp); adapter->psmode = wlan802_11powermodecam; } - adapter->inframode = assoc_req->mode; + adapter->mode = assoc_req->mode; ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib, 0, cmd_option_waitforrsp, OID_802_11_INFRASTRUCTURE_MODE, - (void *) assoc_req->mode); + (void *) (size_t) assoc_req->mode); LEAVE(); return ret; @@ -196,7 +196,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, goto out; /* enable/disable the MAC's WEP packet filter */ - if (assoc_req->secinfo.WEPstatus == wlan802_11WEPenabled) + if (assoc_req->secinfo.wep_enabled) adapter->currentpacketfilter |= cmd_act_mac_wep_enable; else adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable; @@ -300,8 +300,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter, } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { - if (adapter->secinfo.authmode != - assoc_req->secinfo.authmode) { + if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { lbs_pr_debug(1, "Deauthenticating due to updated security " "info in configuration request.\n"); return 1; @@ -316,7 +315,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter, /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - if (assoc_req->mode != wlan802_11infrastructure) + if (assoc_req->mode != IW_MODE_INFRA) return 1; } @@ -333,12 +332,12 @@ static int should_stop_adhoc(wlan_adapter *adapter, if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength) return 1; if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid, - sizeof(struct WLAN_802_11_SSID))) + adapter->curbssparams.ssid.ssidlength)) return 1; /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - if (assoc_req->mode != wlan802_11ibss) + if (assoc_req->mode != IW_MODE_ADHOC) return 1; } @@ -382,7 +381,7 @@ void wlan_association_worker(struct work_struct *work) } if (find_any_ssid) { - enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode; + u8 new_mode; ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid, assoc_req->mode, &new_mode); @@ -393,7 +392,7 @@ void wlan_association_worker(struct work_struct *work) } /* Ensure we switch to the mode of the AP */ - if (assoc_req->mode == wlan802_11autounknown) { + if (assoc_req->mode == IW_MODE_AUTO) { set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); assoc_req->mode = new_mode; } @@ -403,7 +402,7 @@ void wlan_association_worker(struct work_struct *work) * Check if the attributes being changing require deauthentication * from the currently associated infrastructure access point. */ - if (adapter->inframode == wlan802_11infrastructure) { + if (adapter->mode == IW_MODE_INFRA) { if (should_deauth_infrastructure(adapter, assoc_req)) { ret = libertas_send_deauthentication(priv); if (ret) { @@ -412,7 +411,7 @@ void wlan_association_worker(struct work_struct *work) ret); } } - } else if (adapter->inframode == wlan802_11ibss) { + } else if (adapter->mode == IW_MODE_ADHOC) { if (should_stop_adhoc(adapter, assoc_req)) { ret = libertas_stop_adhoc_network(priv); if (ret) { @@ -543,7 +542,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) assoc_req->channel = adapter->curbssparams.channel; if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) - assoc_req->mode = adapter->inframode; + assoc_req->mode = adapter->mode; if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { memcpy(&assoc_req->bssid, adapter->curbssparams.bssid, diff --git a/trunk/drivers/net/wireless/libertas/cmd.c b/trunk/drivers/net/wireless/libertas/cmd.c index bfdac58b5c06..de9cb46a70ff 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.c +++ b/trunk/drivers/net/wireless/libertas/cmd.c @@ -381,15 +381,16 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, switch (cmd_oid) { case OID_802_11_INFRASTRUCTURE_MODE: { - enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode = - (enum WLAN_802_11_NETWORK_INFRASTRUCTURE) pdata_buf; + u8 mode = (u8) (size_t) pdata_buf; pSNMPMIB->querytype = cpu_to_le16(cmd_act_set); pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i); pSNMPMIB->bufsize = sizeof(u8); - if (mode == wlan802_11infrastructure) - ucTemp = SNMP_MIB_VALUE_INFRA; - else + if (mode == IW_MODE_ADHOC) { ucTemp = SNMP_MIB_VALUE_ADHOC; + } else { + /* Infra and Auto modes */ + ucTemp = SNMP_MIB_VALUE_INFRA; + } memmove(pSNMPMIB->value, &ucTemp, sizeof(u8)); @@ -947,8 +948,8 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u spin_unlock_irqrestore(&adapter->driver_lock, flags); - lbs_pr_debug(1, "QUEUE_CMD: Inserted node=0x%x, cmd=0x%x in cmdpendingq\n", - (u32) cmdnode, + lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n", + cmdnode, ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command); done: @@ -976,8 +977,8 @@ static int DownloadcommandToStation(wlan_private * priv, ENTER(); if (!adapter || !cmdnode) { - lbs_pr_debug(1, "DNLD_CMD: adapter = %#x, cmdnode = %#x\n", - (int)adapter, (int)cmdnode); + lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n", + adapter, cmdnode); if (cmdnode) { spin_lock_irqsave(&adapter->driver_lock, flags); __libertas_cleanup_and_insert_cmd(priv, cmdnode); @@ -1174,8 +1175,8 @@ int libertas_prepare_and_send_command(wlan_private * priv, cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; - lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr =0x%x, command=0x%X\n", - (u32) cmdptr, cmd_no); + lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n", + cmdptr, cmd_no); if (!cmdptr) { lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n"); diff --git a/trunk/drivers/net/wireless/libertas/cmdresp.c b/trunk/drivers/net/wireless/libertas/cmdresp.c index cdb012c7e9cf..c86454034b58 100644 --- a/trunk/drivers/net/wireless/libertas/cmdresp.c +++ b/trunk/drivers/net/wireless/libertas/cmdresp.c @@ -72,8 +72,6 @@ void libertas_mac_event_disconnected(wlan_private * priv) adapter->secinfo.WPAenabled = 0; adapter->secinfo.WPA2enabled = 0; adapter->wpa_ie_len = 0; - adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE; - adapter->secinfo.Encryptionmode = CIPHER_NONE; adapter->connect_status = libertas_disconnected; @@ -811,7 +809,7 @@ int libertas_process_rx_command(wlan_private * priv) if (result) { lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n", resp->result); - if (adapter->inframode == wlan802_11ibss) { + if (adapter->mode == IW_MODE_ADHOC) { /* * We should not re-try enter-ps command in * ad-hoc mode. It takes place in diff --git a/trunk/drivers/net/wireless/libertas/debugfs.c b/trunk/drivers/net/wireless/libertas/debugfs.c index 51dfd202f558..7d7bc5e86a56 100644 --- a/trunk/drivers/net/wireless/libertas/debugfs.c +++ b/trunk/drivers/net/wireless/libertas/debugfs.c @@ -7,6 +7,7 @@ #include "dev.h" #include "decl.h" #include "host.h" +#include "debugfs.h" static struct dentry *libertas_dir = NULL; static char *szStates[] = { @@ -276,7 +277,7 @@ static void libertas_parse_ssid(char *buf, size_t count, if (!end) end = buf + count - 1; - size = min(IW_ESSID_MAX_SIZE, end - hold); + size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold)); strncpy(scan_cfg->specificSSID, hold, size); return; @@ -1648,7 +1649,7 @@ struct libertas_debugfs_files { struct file_operations fops; }; -struct libertas_debugfs_files debugfs_files[] = { +static struct libertas_debugfs_files debugfs_files[] = { { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), }, { "getscantable", 0444, FOPS(libertas_getscantable, write_file_dummy), }, @@ -1658,7 +1659,7 @@ struct libertas_debugfs_files debugfs_files[] = { { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), }, }; -struct libertas_debugfs_files debugfs_events_files[] = { +static struct libertas_debugfs_files debugfs_events_files[] = { {"low_rssi", 0644, FOPS(libertas_lowrssi_read, libertas_lowrssi_write), }, {"low_snr", 0644, FOPS(libertas_lowsnr_read, @@ -1673,7 +1674,7 @@ struct libertas_debugfs_files debugfs_events_files[] = { libertas_highsnr_write), }, }; -struct libertas_debugfs_files debugfs_regs_files[] = { +static struct libertas_debugfs_files debugfs_regs_files[] = { {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), }, {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), }, {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), }, @@ -1778,7 +1779,7 @@ void libertas_debugfs_remove_one(wlan_private *priv) struct debug_data { char name[32]; u32 size; - u32 addr; + size_t addr; }; /* To debug any member of wlan_adapter, simply add one line here. @@ -1825,6 +1826,8 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf, val = *((u16 *) d[i].addr); else if (d[i].size == 4) val = *((u32 *) d[i].addr); + else if (d[i].size == 8) + val = *((u64 *) d[i].addr); pos += sprintf(p + pos, "%s=%d\n", d[i].name, val); } @@ -1844,7 +1847,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf, * @param data data to write * @return number of data */ -static int wlan_debugfs_write(struct file *f, const char __user *buf, +static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf, size_t cnt, loff_t *ppos) { int r, i; @@ -1886,12 +1889,14 @@ static int wlan_debugfs_write(struct file *f, const char __user *buf, *((u16 *) d[i].addr) = (u16) r; else if (d[i].size == 4) *((u32 *) d[i].addr) = (u32) r; + else if (d[i].size == 8) + *((u64 *) d[i].addr) = (u64) r; break; } while (1); } kfree(pdata); - return cnt; + return (ssize_t)cnt; } static struct file_operations libertas_debug_fops = { @@ -1916,20 +1921,10 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev) return; for (i = 0; i < num_of_items; i++) - items[i].addr += (u32) priv->adapter; + items[i].addr += (size_t) priv->adapter; priv->debugfs_debug = debugfs_create_file("debug", 0644, priv->debugfs_dir, &items[0], &libertas_debug_fops); } -/** - * @brief remove proc file - * - * @param priv pointer wlan_private - * @return N/A - */ -void libertas_debug_remove(wlan_private * priv) -{ - debugfs_remove(priv->debugfs_debug); -} diff --git a/trunk/drivers/net/wireless/libertas/defs.h b/trunk/drivers/net/wireless/libertas/defs.h index fb1478c1b87d..80dd9ea19c8e 100644 --- a/trunk/drivers/net/wireless/libertas/defs.h +++ b/trunk/drivers/net/wireless/libertas/defs.h @@ -9,6 +9,11 @@ extern unsigned int libertas_debug; +#ifdef CONFIG_LIBERTAS_DEBUG +#define DEBUG +#define PROC_DEBUG +#endif + #define DRV_NAME "usb8xxx" #define lbs_pr_info(format, args...) \ @@ -223,31 +228,6 @@ enum SNRNF_DATA { MAX_TYPE_AVG }; -/** WLAN_802_11_AUTH_ALG*/ -enum WLAN_802_11_AUTH_ALG { - AUTH_ALG_OPEN_SYSTEM = 1, - AUTH_ALG_SHARED_KEY = 2, - AUTH_ALG_NETWORK_EAP = 8, -}; - -/** WLAN_802_1X_AUTH_ALG */ -enum WLAN_802_1X_AUTH_ALG { - WLAN_1X_AUTH_ALG_NONE = 1, - WLAN_1X_AUTH_ALG_LEAP = 2, - WLAN_1X_AUTH_ALG_TLS = 4, - WLAN_1X_AUTH_ALG_TTLS = 8, - WLAN_1X_AUTH_ALG_MD5 = 16, -}; - -/** WLAN_802_11_ENCRYPTION_MODE */ -enum WLAN_802_11_ENCRYPTION_MODE { - CIPHER_NONE, - CIPHER_WEP40, - CIPHER_TKIP, - CIPHER_CCMP, - CIPHER_WEP104, -}; - /** WLAN_802_11_POWER_MODE */ enum WLAN_802_11_POWER_MODE { wlan802_11powermodecam, @@ -292,28 +272,6 @@ enum mv_ms_type { MVMS_EVENT }; -/** WLAN_802_11_NETWORK_INFRASTRUCTURE */ -enum WLAN_802_11_NETWORK_INFRASTRUCTURE { - wlan802_11ibss, - wlan802_11infrastructure, - wlan802_11autounknown, - /*defined as upper bound */ - wlan802_11infrastructuremax -}; - -/** WLAN_802_11_AUTHENTICATION_MODE */ -enum WLAN_802_11_AUTHENTICATION_MODE { - wlan802_11authmodeopen = 0x00, - wlan802_11authmodeshared = 0x01, - wlan802_11authmodenetworkEAP = 0x80, -}; - -/** WLAN_802_11_WEP_STATUS */ -enum WLAN_802_11_WEP_STATUS { - wlan802_11WEPenabled, - wlan802_11WEPdisabled, -}; - /** SNMP_MIB_INDEX_e */ enum SNMP_MIB_INDEX_e { desired_bsstype_i = 0, diff --git a/trunk/drivers/net/wireless/libertas/dev.h b/trunk/drivers/net/wireless/libertas/dev.h index b1f876f9693b..e8b9020f9bd6 100644 --- a/trunk/drivers/net/wireless/libertas/dev.h +++ b/trunk/drivers/net/wireless/libertas/dev.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "defs.h" #include "scan.h" @@ -56,10 +57,8 @@ struct region_channel { struct wlan_802_11_security { u8 WPAenabled; u8 WPA2enabled; - enum WLAN_802_11_WEP_STATUS WEPstatus; - enum WLAN_802_11_AUTHENTICATION_MODE authmode; - enum WLAN_802_1X_AUTH_ALG auth1xalg; - enum WLAN_802_11_ENCRYPTION_MODE Encryptionmode; + u8 wep_enabled; + u8 auth_mode; }; /** Current Basic Service Set State Structure */ @@ -184,7 +183,7 @@ struct assoc_request { struct WLAN_802_11_SSID ssid; u8 channel; - enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode; + u8 mode; u8 bssid[ETH_ALEN]; /** WEP keys */ @@ -198,7 +197,6 @@ struct assoc_request { struct wlan_802_11_security secinfo; /** WPA Information Elements*/ -#define MAX_WPA_IE_LEN 64 u8 wpa_ie[MAX_WPA_IE_LEN]; u8 wpa_ie_len; }; @@ -254,7 +252,8 @@ struct _wlan_adapter { /** current ssid/bssid related parameters*/ struct current_bss_params curbssparams; - enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode; + /* IW_MODE_* */ + u8 mode; struct bss_descriptor *pattemptedbssdesc; @@ -339,7 +338,6 @@ struct _wlan_adapter { struct WLAN_802_11_KEY wpa_unicast_key; /** WPA Information Elements*/ -#define MAX_WPA_IE_LEN 64 u8 wpa_ie[MAX_WPA_IE_LEN]; u8 wpa_ie_len; diff --git a/trunk/drivers/net/wireless/libertas/fw.c b/trunk/drivers/net/wireless/libertas/fw.c index b194a4570791..441123c85e62 100644 --- a/trunk/drivers/net/wireless/libertas/fw.c +++ b/trunk/drivers/net/wireless/libertas/fw.c @@ -194,16 +194,13 @@ static void wlan_init_adapter(wlan_private * priv) adapter->scanmode = cmd_bss_type_any; /* 802.11 specific */ - adapter->secinfo.WEPstatus = wlan802_11WEPdisabled; + adapter->secinfo.wep_enabled = 0; for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]); i++) memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY)); adapter->wep_tx_keyidx = 0; - adapter->secinfo.WEPstatus = wlan802_11WEPdisabled; - adapter->secinfo.authmode = wlan802_11authmodeopen; - adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE; - adapter->secinfo.Encryptionmode = CIPHER_NONE; - adapter->inframode = wlan802_11infrastructure; + adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; + adapter->mode = IW_MODE_INFRA; adapter->assoc_req = NULL; diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index 695fb6a66ffe..ae6f72a6cdf3 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -388,7 +388,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv, usb_fill_bulk_urb(cardp->rx_urb, cardp->udev, usb_rcvbulkpipe(cardp->udev, cardp->bulk_in_endpointAddr), - skb->tail + IPFIELD_ALIGN_OFFSET, + (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET), MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, rinfo); @@ -626,6 +626,7 @@ static void if_usb_receive(struct urb *urb) cardp->usb_event_cause); if (cardp->usb_event_cause & 0xffff0000) { libertas_send_tx_feedback(priv); + spin_unlock(&priv->adapter->driver_lock); break; } cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3; @@ -775,7 +776,6 @@ int libertas_sbi_prog_firmware(wlan_private * priv) return -1; } -#ifdef SUPPORT_BOOT_COMMAND cardp->bootcmdresp = 0; do { int j = 0; @@ -796,7 +796,6 @@ int libertas_sbi_prog_firmware(wlan_private * priv) } return -1; } -#endif i = 0; priv->adapter->fw_ready = 0; diff --git a/trunk/drivers/net/wireless/libertas/if_usb.h b/trunk/drivers/net/wireless/libertas/if_usb.h index 785116720bc6..170dfe6809f5 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.h +++ b/trunk/drivers/net/wireless/libertas/if_usb.h @@ -12,7 +12,6 @@ #define USB8388_VID_2 0x05a3 #define USB8388_PID_2 0x8388 -#ifdef SUPPORT_BOOT_COMMAND #define BOOT_CMD_FW_BY_USB 0x01 #define BOOT_CMD_FW_IN_EEPROM 0x02 #define BOOT_CMD_UPDATE_BOOT2 0x03 @@ -36,7 +35,6 @@ struct bootcmdrespStr u8 u8result; u8 au8dumy[2]; }; -#endif /* SUPPORT_BOOT_COMMAND */ /* read callback private data */ struct read_cb_info { diff --git a/trunk/drivers/net/wireless/libertas/ioctl.c b/trunk/drivers/net/wireless/libertas/ioctl.c index 82b39642423a..a8f76c358992 100644 --- a/trunk/drivers/net/wireless/libertas/ioctl.c +++ b/trunk/drivers/net/wireless/libertas/ioctl.c @@ -27,1112 +27,31 @@ #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ) -static int setrxantenna(wlan_private * priv, int mode) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2 - && mode != RF_ANTENNA_AUTO) { - return -EINVAL; - } - - adapter->rxantennamode = mode; - - lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode); - - ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna, - cmd_act_set_rx, - cmd_option_waitforrsp, 0, - &adapter->rxantennamode); - return ret; -} - -static int settxantenna(wlan_private * priv, int mode) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2) - && (mode != RF_ANTENNA_AUTO)) { - return -EINVAL; - } - - adapter->txantennamode = mode; - - lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode); - - ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna, - cmd_act_set_tx, - cmd_option_waitforrsp, 0, - &adapter->txantennamode); - - return ret; -} - -static int getrxantenna(wlan_private * priv, char *buf) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - // clear it, so we will know if the value - // returned below is correct or not. - adapter->rxantennamode = 0; - - ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna, - cmd_act_get_rx, - cmd_option_waitforrsp, 0, NULL); - - if (ret) { - LEAVE(); - return ret; - } - - lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode); - - return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1; -} - -static int gettxantenna(wlan_private * priv, char *buf) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - // clear it, so we will know if the value - // returned below is correct or not. - adapter->txantennamode = 0; - - ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna, - cmd_act_get_tx, - cmd_option_waitforrsp, 0, NULL); - - if (ret) { - LEAVE(); - return ret; - } - - lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode); - - return sprintf(buf, "0x%04x", adapter->txantennamode) + 1; -} - -static int wlan_set_region(wlan_private * priv, u16 region_code) -{ - int i; - - for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { - // use the region code to search for the index - if (region_code == libertas_region_code_to_index[i]) { - priv->adapter->regiontableindex = (u16) i; - priv->adapter->regioncode = region_code; - break; - } - } - - // if it's unidentified region code - if (i >= MRVDRV_MAX_REGION_CODE) { - lbs_pr_debug(1, "region Code not identified\n"); - LEAVE(); - return -1; - } - - if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { - LEAVE(); - return -EINVAL; - } - - return 0; -} - -/** - * @brief Get/Set Firmware wakeup method - * - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to user data - * @return 0--success, otherwise fail - */ -static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq) -{ - wlan_adapter *adapter = priv->adapter; - int data; - ENTER(); - - if ((int)wrq->u.data.length == 0) { - if (copy_to_user - (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) { - lbs_pr_alert("copy_to_user failed!\n"); - return -EFAULT; - } - } else { - if ((int)wrq->u.data.length > 1) { - lbs_pr_alert("ioctl too many args!\n"); - return -EFAULT; - } - if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_alert("Copy from user failed\n"); - return -EFAULT; - } - - adapter->pkttxctrl = (u32) data; - } - - wrq->u.data.length = 1; - - LEAVE(); - return 0; -} - -/** - * @brief Get/Set NULL Package generation interval - * - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to user data - * @return 0--success, otherwise fail - */ -static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq) -{ - wlan_adapter *adapter = priv->adapter; - int data; - ENTER(); - - if ((int)wrq->u.data.length == 0) { - data = adapter->nullpktinterval; - - if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) { - lbs_pr_alert( "copy_to_user failed!\n"); - return -EFAULT; - } - } else { - if ((int)wrq->u.data.length > 1) { - lbs_pr_alert( "ioctl too many args!\n"); - return -EFAULT; - } - if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - - adapter->nullpktinterval = data; - } - - wrq->u.data.length = 1; - - LEAVE(); - return 0; -} - -static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq) -{ - wlan_adapter *adapter = priv->adapter; - int data[2]; - ENTER(); - data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG]; - data[1] = adapter->rxpd_rate; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - wrq->u.data.length = 2; - LEAVE(); - return 0; -} - -static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - int data[4]; - - ENTER(); - memset(data, 0, sizeof(data)); - if (wrq->u.data.length) { - if (copy_from_user(data, wrq->u.data.pointer, - min_t(size_t, wrq->u.data.length, 4) * sizeof(int))) - return -EFAULT; - } - if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) { - if (adapter->connect_status == libertas_connected) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, - cmd_option_waitforrsp, - 0, NULL); - - if (ret) { - LEAVE(); - return ret; - } - } - } - - if (wrq->u.data.length == 0) { - data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG]; - data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG]; - data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG]; - data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4)) - return -EFAULT; - wrq->u.data.length = 4; - } else if (data[0] == 0) { - data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG]; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int))) - return -EFAULT; - wrq->u.data.length = 1; - } else if (data[0] == 1) { - data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG]; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int))) - return -EFAULT; - wrq->u.data.length = 1; - } else if (data[0] == 2) { - data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG]; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int))) - return -EFAULT; - wrq->u.data.length = 1; - } else if (data[0] == 3) { - data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int))) - return -EFAULT; - wrq->u.data.length = 1; - } else - return -ENOTSUPP; - - LEAVE(); - return 0; -} - -static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq) -{ - int data; - wlan_adapter *adapter = priv->adapter; - - if (wrq->u.data.length > 0) { - if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) - return -EFAULT; - - lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data); - if ((data > MRVDRV_MAX_BEACON_INTERVAL) - || (data < MRVDRV_MIN_BEACON_INTERVAL)) - return -ENOTSUPP; - adapter->beaconperiod = data; - } - data = adapter->beaconperiod; - if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) - return -EFAULT; - - wrq->u.data.length = 1; - - return 0; -} - -static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - int temp; - int data = 0; - int *val; - - ENTER(); - data = SUBCMD_DATA(wrq); - if ((data == 0) || (data == 1)) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, cmd_option_waitforrsp, - 0, NULL); - if (ret) { - LEAVE(); - return ret; - } - } - - switch (data) { - case 0: - - temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG], - adapter->NF[TYPE_BEACON][TYPE_NOAVG]); - break; - case 1: - temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG], - adapter->NF[TYPE_BEACON][TYPE_AVG]); - break; - case 2: - temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG], - adapter->NF[TYPE_RXPD][TYPE_NOAVG]); - break; - case 3: - temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, - adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); - break; - default: - return -ENOTSUPP; - } - val = (int *)wrq->u.name; - *val = temp; - - LEAVE(); - return 0; -} - -static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq) -{ - int ret = 0; - wlan_adapter *adapter = priv->adapter; - int temp; - int data = 0; - int *val; - - data = SUBCMD_DATA(wrq); - if ((data == 0) || (data == 1)) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rssi, - 0, cmd_option_waitforrsp, - 0, NULL); - - if (ret) { - LEAVE(); - return ret; - } - } - - switch (data) { - case 0: - temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG]; - break; - case 1: - temp = adapter->NF[TYPE_BEACON][TYPE_AVG]; - break; - case 2: - temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG]; - break; - case 3: - temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; - break; - default: - return -ENOTSUPP; - } - - temp = CAL_NF(temp); - - lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp); - val = (int *)wrq->u.name; - *val = temp; - return 0; -} - -static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req) -{ - wlan_adapter *adapter = priv->adapter; - int *pdata; - struct iwreq *wrq = (struct iwreq *)req; - int ret = 0; - adapter->txrate = 0; - lbs_pr_debug(1, "wlan_get_txrate_ioctl\n"); - ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query, - cmd_act_get, cmd_option_waitforrsp, - 0, NULL); - if (ret) - return ret; - - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->txrate; - return 0; -} - -static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - char status[64]; - wlan_adapter *adapter = priv->adapter; - - memset(status, 0, sizeof(status)); - - switch (adapter->inframode) { - case wlan802_11ibss: - if (adapter->connect_status == libertas_connected) { - if (adapter->adhoccreate) - memcpy(&status, "AdhocStarted", sizeof(status)); - else - memcpy(&status, "AdhocJoined", sizeof(status)); - } else { - memcpy(&status, "AdhocIdle", sizeof(status)); - } - break; - case wlan802_11infrastructure: - memcpy(&status, "Inframode", sizeof(status)); - break; - default: - memcpy(&status, "AutoUnknownmode", sizeof(status)); - break; - } - - lbs_pr_debug(1, "status = %s\n", status); - wrq->u.data.length = strlen(status) + 1; - - if (wrq->u.data.pointer) { - if (copy_to_user(wrq->u.data.pointer, - &status, wrq->u.data.length)) - return -EFAULT; - } - - LEAVE(); - return 0; -} - -/** - * @brief Set/Get WPA IE - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - wlan_adapter *adapter = priv->adapter; - int ret = 0; - - ENTER(); - - if (wrq->u.data.length) { - if (wrq->u.data.length > sizeof(adapter->wpa_ie)) { - lbs_pr_debug(1, "failed to copy WPA IE, too big \n"); - return -EFAULT; - } - if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer, - wrq->u.data.length)) { - lbs_pr_debug(1, "failed to copy WPA IE \n"); - return -EFAULT; - } - adapter->wpa_ie_len = wrq->u.data.length; - lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len, - adapter->wpa_ie[0]); - lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len); - if (adapter->wpa_ie[0] == WPA_IE) - adapter->secinfo.WPAenabled = 1; - else if (adapter->wpa_ie[0] == WPA2_IE) - adapter->secinfo.WPA2enabled = 1; - else { - adapter->secinfo.WPAenabled = 0; - adapter->secinfo.WPA2enabled = 0; - } - } else { - memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie)); - adapter->wpa_ie_len = wrq->u.data.length; - lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n", - adapter->wpa_ie_len, adapter->wpa_ie[0]); - adapter->secinfo.WPAenabled = 0; - adapter->secinfo.WPA2enabled = 0; - } - - // enable/disable RSN in firmware if WPA is enabled/disabled - // depending on variable adapter->secinfo.WPAenabled is set or not - ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn, - cmd_act_set, cmd_option_waitforrsp, - 0, NULL); - - LEAVE(); - return ret; -} - -/** - * @brief Set Auto prescan - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to iwreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - int data; - wlan_adapter *adapter = priv->adapter; - int *val; - - data = SUBCMD_DATA(wrq); - lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data); - adapter->prescan = data; - - val = (int *)wrq->u.name; - *val = data; - return 0; -} - -static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - u32 mdtim; - int idata; - int ret = -EINVAL; - - ENTER(); - - idata = SUBCMD_DATA(wrq); - mdtim = (u32) idata; - if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM) - && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM)) - || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) { - priv->adapter->multipledtim = mdtim; - ret = 0; - } - if (ret) - lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n"); - - LEAVE(); - return ret; -} - -/** - * @brief Set authentication mode - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req) -{ - int alg; - struct iwreq *wrq = (struct iwreq *)req; - wlan_adapter *adapter = priv->adapter; - - if (wrq->u.data.flags == 0) { - //from iwpriv subcmd - alg = SUBCMD_DATA(wrq); - } else { - //from wpa_supplicant subcmd - if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - } - - lbs_pr_debug(1, "auth alg is %#x\n", alg); - - switch (alg) { - case AUTH_ALG_SHARED_KEY: - adapter->secinfo.authmode = wlan802_11authmodeshared; - break; - case AUTH_ALG_NETWORK_EAP: - adapter->secinfo.authmode = - wlan802_11authmodenetworkEAP; - break; - case AUTH_ALG_OPEN_SYSTEM: - default: - adapter->secinfo.authmode = wlan802_11authmodeopen; - break; - } - return 0; -} - -/** - * @brief Set 802.1x authentication mode - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req) -{ - int alg; - struct iwreq *wrq = (struct iwreq *)req; - - if (wrq->u.data.flags == 0) { - //from iwpriv subcmd - alg = SUBCMD_DATA(wrq); - } else { - //from wpa_supplicant subcmd - if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - } - lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg); - priv->adapter->secinfo.auth1xalg = alg; - return 0; -} - -static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req) -{ - int mode; - struct iwreq *wrq = (struct iwreq *)req; - - ENTER(); - - if (wrq->u.data.flags == 0) { - //from iwpriv subcmd - mode = SUBCMD_DATA(wrq); - } else { - //from wpa_supplicant subcmd - if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - } - lbs_pr_debug(1, "encryption mode is %#x\n", mode); - priv->adapter->secinfo.Encryptionmode = mode; - - LEAVE(); - return 0; -} - -static void adjust_mtu(wlan_private * priv) -{ - int mtu_increment = 0; - - if (priv->adapter->linkmode == WLAN_LINKMODE_802_11) - mtu_increment += sizeof(struct ieee80211_hdr_4addr); - - if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) - mtu_increment += max(sizeof(struct tx_radiotap_hdr), - sizeof(struct rx_radiotap_hdr)); - priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN - - sizeof(struct ethhdr) - + mtu_increment; -} - -/** - * @brief Set Link-Layer Layer mode - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req) -{ - int mode; - - mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data; - - switch (mode) { - case WLAN_LINKMODE_802_3: - priv->adapter->linkmode = mode; - break; - case WLAN_LINKMODE_802_11: - priv->adapter->linkmode = mode; - break; - default: - lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n", - mode); - return -EINVAL; - break; - } - lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode); - - adjust_mtu(priv); - - return 0; -} - -/** - * @brief Set Radio header mode - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req) -{ - int mode; - - mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data; - - switch (mode) { - case WLAN_RADIOMODE_NONE: - priv->adapter->radiomode = mode; - break; - case WLAN_RADIOMODE_RADIOTAP: - priv->adapter->radiomode = mode; - break; - default: - lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n", - mode); - return -EINVAL; - } - lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode); - - adjust_mtu(priv); - return 0; -} - -/** - * @brief Set Debug header mode - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req) -{ - priv->adapter->debugmode = (int)((struct ifreq *) - ((u8 *) req + 4))->ifr_data; - return 0; -} - -static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv, - struct ifreq *req) -{ - int len; - char buf[8]; - struct iwreq *wrq = (struct iwreq *)req; - - lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n"); - len = getrxantenna(priv, buf); - - wrq->u.data.length = len; - if (wrq->u.data.pointer) { - if (copy_to_user(wrq->u.data.pointer, &buf, len)) { - lbs_pr_debug(1, "CopyToUser failed\n"); - return -EFAULT; - } - } - - return 0; -} - -static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv, - struct ifreq *req) -{ - int len; - char buf[8]; - struct iwreq *wrq = (struct iwreq *)req; - - lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n"); - len = gettxantenna(priv, buf); - - wrq->u.data.length = len; - if (wrq->u.data.pointer) { - if (copy_to_user(wrq->u.data.pointer, &buf, len)) { - lbs_pr_debug(1, "CopyToUser failed\n"); - return -EFAULT; - } - } - return 0; -} - -/** - * @brief Get the MAC TSF value from the firmware - * - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to iwreq structure containing buffer - * space to store a TSF value retrieved from the firmware - * - * @return 0 if successful; IOCTL error code otherwise - */ -static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - u64 tsfval; - int ret; - - ret = libertas_prepare_and_send_command(priv, - cmd_get_tsf, - 0, cmd_option_waitforrsp, 0, &tsfval); - - lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval); - - if (ret != 0) { - lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n"); - ret = -EFAULT; - } else { - if (copy_to_user(wrq->u.data.pointer, - &tsfval, - min_t(size_t, wrq->u.data.length, - sizeof(tsfval))) != 0) { - - lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n"); - ret = -EFAULT; - } else { - ret = 0; - } - } - return ret; -} - -/** - * @brief Get/Set adapt rate - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to iwreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq) -{ - int ret; - wlan_adapter *adapter = priv->adapter; - int data[2]; - - memset(data, 0, sizeof(data)); - if (!wrq->u.data.length) { - lbs_pr_debug(1, "Get ADAPT RATE SET\n"); - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rate_adapt_rateset, - cmd_act_get, - cmd_option_waitforrsp, 0, NULL); - data[0] = adapter->enablehwauto; - data[1] = adapter->ratebitmap; - if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } -#define GET_TWO_INT 2 - wrq->u.data.length = GET_TWO_INT; - } else { - lbs_pr_debug(1, "Set ADAPT RATE SET\n"); - if (wrq->u.data.length > 2) - return -EINVAL; - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * wrq->u.data.length)) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - - adapter->enablehwauto = data[0]; - adapter->ratebitmap = data[1]; - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_rate_adapt_rateset, - cmd_act_set, - cmd_option_waitforrsp, 0, NULL); - } - return ret; -} - -/** - * @brief Get/Set inactivity timeout - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to iwreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq) -{ - int ret; - int data = 0; - u16 timeout = 0; - - ENTER(); - if (wrq->u.data.length > 1) - return -ENOTSUPP; - - if (wrq->u.data.length == 0) { - /* Get */ - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_inactivity_timeout, - cmd_act_get, - cmd_option_waitforrsp, 0, - &timeout); - data = timeout; - if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - } else { - /* Set */ - if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - - timeout = data; - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_inactivity_timeout, - cmd_act_set, - cmd_option_waitforrsp, 0, - &timeout); - } - - wrq->u.data.length = 1; - - LEAVE(); - return ret; -} - -static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - int ret; - char buf[GETLOG_BUFSIZE - 1]; - wlan_adapter *adapter = priv->adapter; - - lbs_pr_debug(1, " GET STATS\n"); - - ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log, - 0, cmd_option_waitforrsp, 0, NULL); - - if (ret) { - return ret; - } - - if (wrq->u.data.pointer) { - sprintf(buf, "\n mcasttxframe %u failed %u retry %u " - "multiretry %u framedup %u " - "rtssuccess %u rtsfailure %u ackfailure %u\n" - "rxfrag %u mcastrxframe %u fcserror %u " - "txframe %u wepundecryptable %u ", - adapter->logmsg.mcasttxframe, - adapter->logmsg.failed, - adapter->logmsg.retry, - adapter->logmsg.multiretry, - adapter->logmsg.framedup, - adapter->logmsg.rtssuccess, - adapter->logmsg.rtsfailure, - adapter->logmsg.ackfailure, - adapter->logmsg.rxfrag, - adapter->logmsg.mcastrxframe, - adapter->logmsg.fcserror, - adapter->logmsg.txframe, - adapter->logmsg.wepundecryptable); - wrq->u.data.length = strlen(buf) + 1; - if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - } - - return 0; -} - -static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - u8 buf[12]; - u8 *option[] = { "active", "passive", "get", }; - int i, max_options = (sizeof(option) / sizeof(option[0])); - int ret = 0; - wlan_adapter *adapter = priv->adapter; - - if (priv->adapter->enable11d) { - lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n"); - return -EFAULT; - } - - memset(buf, 0, sizeof(buf)); - - if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf), - wrq->u.data.length))) - return -EFAULT; - - lbs_pr_debug(1, "Scan type Option = %s\n", buf); - - buf[sizeof(buf) - 1] = '\0'; - - for (i = 0; i < max_options; i++) { - if (!strcmp(buf, option[i])) - break; - } - - switch (i) { - case 0: - adapter->scantype = cmd_scan_type_active; - break; - case 1: - adapter->scantype = cmd_scan_type_passive; - break; - case 2: - wrq->u.data.length = strlen(option[adapter->scantype]) + 1; - - if (copy_to_user(wrq->u.data.pointer, - option[adapter->scantype], - wrq->u.data.length)) { - lbs_pr_debug(1, "Copy to user failed\n"); - ret = -EFAULT; - } - - break; - default: - lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n"); - ret = -EINVAL; - break; - } - - return ret; -} - -static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - wlan_adapter *adapter = priv->adapter; - u8 buf[12]; - u8 *option[] = { "bss", "ibss", "any", "get" }; - int i, max_options = (sizeof(option) / sizeof(option[0])); - int ret = 0; - - ENTER(); - - memset(buf, 0, sizeof(buf)); - - if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf), - wrq->u.data.length))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - - lbs_pr_debug(1, "Scan mode Option = %s\n", buf); - - buf[sizeof(buf) - 1] = '\0'; +static int wlan_set_region(wlan_private * priv, u16 region_code) +{ + int i; - for (i = 0; i < max_options; i++) { - if (!strcmp(buf, option[i])) + for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { + // use the region code to search for the index + if (region_code == libertas_region_code_to_index[i]) { + priv->adapter->regiontableindex = (u16) i; + priv->adapter->regioncode = region_code; break; - } - - switch (i) { - - case 0: - adapter->scanmode = cmd_bss_type_bss; - break; - case 1: - adapter->scanmode = cmd_bss_type_ibss; - break; - case 2: - adapter->scanmode = cmd_bss_type_any; - break; - case 3: - - wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1; - - lbs_pr_debug(1, "Get Scan mode Option = %s\n", - option[adapter->scanmode - 1]); - - lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length); - - if (copy_to_user(wrq->u.data.pointer, - option[adapter->scanmode - 1], - wrq->u.data.length)) { - lbs_pr_debug(1, "Copy to user failed\n"); - ret = -EFAULT; } - lbs_pr_debug(1, "GET Scan type Option after copy = %s\n", - (char *)wrq->u.data.pointer); - - break; - - default: - lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n"); - ret = -EINVAL; - break; } - LEAVE(); - return ret; -} - -/** - * @brief Get/Set Adhoc G Rate - * - * @param priv A pointer to wlan_private structure - * @param wrq A pointer to user data - * @return 0--success, otherwise fail - */ -static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq) -{ - wlan_adapter *adapter = priv->adapter; - int data, data1; - int *val; - - ENTER(); + // if it's unidentified region code + if (i >= MRVDRV_MAX_REGION_CODE) { + lbs_pr_debug(1, "region Code not identified\n"); + LEAVE(); + return -1; + } - data1 = SUBCMD_DATA(wrq); - switch (data1) { - case 0: - adapter->adhoc_grate_enabled = 0; - break; - case 1: - adapter->adhoc_grate_enabled = 1; - break; - case 2: - break; - default: + if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { + LEAVE(); return -EINVAL; } - data = adapter->adhoc_grate_enabled; - val = (int *)wrq->u.name; - *val = data; - LEAVE(); + return 0; } @@ -1761,6 +680,7 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req) */ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) { + struct iwreq *wrq = (struct iwreq *)req; static struct cmd_ds_fwt_access fwt_access; int ret; @@ -1776,7 +696,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) (void *)&fwt_access); if (ret == 0) - req->ifr_data = (char *)(le32_to_cpu(fwt_access.references)); + wrq->u.param.value = le32_to_cpu(fwt_access.references); else return -EFAULT; @@ -1792,6 +712,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) */ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) { + struct iwreq *wrq = (struct iwreq *)req; static struct cmd_ds_fwt_access fwt_access; int ret; @@ -1807,7 +728,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) (void *)&fwt_access); if (ret == 0) - req->ifr_data = (char *)(le32_to_cpu(fwt_access.references)); + wrq->u.param.value = le32_to_cpu(fwt_access.references); else return -EFAULT; @@ -1823,6 +744,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) */ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) { + struct iwreq *wrq = (struct iwreq *)req; struct cmd_ds_mesh_access mesh_access; int ret; @@ -1835,9 +757,8 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) cmd_option_waitforrsp, 0, (void *)&mesh_access); - if (ret == 0) { - req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0])); - } + if (ret == 0) + wrq->u.param.value = le32_to_cpu(mesh_access.data[0]); else return -EFAULT; @@ -1898,36 +819,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd); switch (cmd) { - case WLANSCAN_TYPE: - lbs_pr_debug(1, "Scan type Ioctl\n"); - ret = wlan_scan_type_ioctl(priv, wrq); - break; - case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */ switch (wrq->u.data.flags) { - case WLANDEAUTH: - lbs_pr_debug(1, "Deauth\n"); - libertas_send_deauth(priv); - break; - - case WLANADHOCSTOP: - lbs_pr_debug(1, "Adhoc stop\n"); - ret = libertas_do_adhocstop_ioctl(priv); - break; - - case WLANRADIOON: - wlan_radio_ioctl(priv, 1); - break; - - case WLANRADIOOFF: - wlan_radio_ioctl(priv, 0); - break; - case WLANWLANIDLEON: - libertas_idle_on(priv); - break; - case WLANWLANIDLEOFF: - libertas_idle_off(priv); - break; case WLAN_SUBCMD_BT_RESET: /* bt_reset */ wlan_bt_reset_ioctl(priv); break; @@ -1937,162 +830,19 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) } /* End of switch */ break; - case WLANSETWPAIE: - ret = wlan_setwpaie_ioctl(priv, req); - break; - case WLAN_SETINT_GETINT: - /* The first 4 bytes of req->ifr_data is sub-ioctl number - * after 4 bytes sits the payload. - */ - subcmd = (int)req->ifr_data; //from iwpriv subcmd - switch (subcmd) { - case WLANNF: - ret = wlan_get_nf(priv, wrq); - break; - case WLANRSSI: - ret = wlan_get_rssi(priv, wrq); - break; - case WLANENABLE11D: - ret = libertas_cmd_enable_11d(priv, wrq); - break; - case WLANADHOCGRATE: - ret = wlan_do_set_grate_ioctl(priv, wrq); - break; - case WLAN_SUBCMD_SET_PRESCAN: - ret = wlan_subcmd_setprescan_ioctl(priv, wrq); - break; - } - break; - - case WLAN_SETONEINT_GETONEINT: - switch (wrq->u.data.flags) { - case WLAN_BEACON_INTERVAL: - ret = wlan_beacon_interval(priv, wrq); - break; - - case WLAN_LISTENINTRVL: - if (!wrq->u.data.length) { - int data; - lbs_pr_debug(1, "Get locallisteninterval value\n"); -#define GET_ONE_INT 1 - data = adapter->locallisteninterval; - if (copy_to_user(wrq->u.data.pointer, - &data, sizeof(int))) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = GET_ONE_INT; - } else { - int data; - if (copy_from_user - (&data, wrq->u.data.pointer, sizeof(int))) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - - lbs_pr_debug(1, "Set locallisteninterval = %d\n", - data); -#define MAX_U16_VAL 65535 - if (data > MAX_U16_VAL) { - lbs_pr_debug(1, "Exceeds U16 value\n"); - return -EINVAL; - } - adapter->locallisteninterval = data; - } - break; - case WLAN_TXCONTROL: - ret = wlan_txcontrol(priv, wrq); //adds for txcontrol ioctl - break; - - case WLAN_NULLPKTINTERVAL: - ret = wlan_null_pkt_interval(priv, wrq); - break; - - default: - ret = -EOPNOTSUPP; - break; - } - break; - case WLAN_SETONEINT_GETNONE: /* The first 4 bytes of req->ifr_data is sub-ioctl number * after 4 bytes sits the payload. */ - subcmd = wrq->u.data.flags; //from wpa_supplicant subcmd - + subcmd = wrq->u.data.flags; if (!subcmd) - subcmd = (int)req->ifr_data; //from iwpriv subcmd + subcmd = (int)wrq->u.param.value; switch (subcmd) { - case WLAN_SUBCMD_SETRXANTENNA: /* SETRXANTENNA */ - idata = SUBCMD_DATA(wrq); - ret = setrxantenna(priv, idata); - break; - case WLAN_SUBCMD_SETTXANTENNA: /* SETTXANTENNA */ - idata = SUBCMD_DATA(wrq); - ret = settxantenna(priv, idata); - break; - case WLAN_SET_ATIM_WINDOW: - adapter->atimwindow = SUBCMD_DATA(wrq); - adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50); - break; - case WLANSETBCNAVG: - adapter->bcn_avg_factor = SUBCMD_DATA(wrq); - if (adapter->bcn_avg_factor == 0) - adapter->bcn_avg_factor = - DEFAULT_BCN_AVG_FACTOR; - if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR) - adapter->bcn_avg_factor = - DEFAULT_BCN_AVG_FACTOR; - break; - case WLANSETDATAAVG: - adapter->data_avg_factor = SUBCMD_DATA(wrq); - if (adapter->data_avg_factor == 0) - adapter->data_avg_factor = - DEFAULT_DATA_AVG_FACTOR; - if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR) - adapter->data_avg_factor = - DEFAULT_DATA_AVG_FACTOR; - break; case WLANSETREGION: idata = SUBCMD_DATA(wrq); ret = wlan_set_region(priv, (u16) idata); break; - - case WLAN_SET_LISTEN_INTERVAL: - idata = SUBCMD_DATA(wrq); - adapter->listeninterval = (u16) idata; - break; - - case WLAN_SET_MULTIPLE_DTIM: - ret = wlan_set_multiple_dtim_ioctl(priv, req); - break; - - case WLANSETAUTHALG: - ret = wlan_setauthalg_ioctl(priv, req); - break; - - case WLANSET8021XAUTHALG: - ret = wlan_set8021xauthalg_ioctl(priv, req); - break; - - case WLANSETENCRYPTIONMODE: - ret = wlan_setencryptionmode_ioctl(priv, req); - break; - - case WLAN_SET_LINKMODE: - ret = wlan_set_linkmode_ioctl(priv, req); - break; - - case WLAN_SET_RADIOMODE: - ret = wlan_set_radiomode_ioctl(priv, req); - break; - - case WLAN_SET_DEBUGMODE: - ret = wlan_set_debugmode_ioctl(priv, req); - break; - case WLAN_SUBCMD_MESH_SET_TTL: idata = SUBCMD_DATA(wrq); ret = wlan_mesh_set_ttl_ioctl(priv, idata); @@ -2105,38 +855,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) break; - case WLAN_SETNONE_GETTWELVE_CHAR: /* Get Antenna settings */ - /* - * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is - * in flags of iwreq structure, otherwise it will be in - * mode member of iwreq structure. - */ - switch ((int)wrq->u.data.flags) { - case WLAN_SUBCMD_GETRXANTENNA: /* Get Rx Antenna */ - ret = wlan_subcmd_getrxantenna_ioctl(priv, req); - break; - - case WLAN_SUBCMD_GETTXANTENNA: /* Get Tx Antenna */ - ret = wlan_subcmd_gettxantenna_ioctl(priv, req); - break; - - case WLAN_GET_TSF: - ret = wlan_get_tsf_ioctl(priv, wrq); - break; - } - break; - case WLAN_SET128CHAR_GET128CHAR: switch ((int)wrq->u.data.flags) { - - case WLANSCAN_MODE: - lbs_pr_debug(1, "Scan mode Ioctl\n"); - ret = wlan_scan_mode_ioctl(priv, wrq); - break; - - case WLAN_GET_ADHOC_STATUS: - ret = wlan_get_adhoc_status_ioctl(priv, wrq); - break; case WLAN_SUBCMD_BT_ADD: ret = wlan_bt_add_ioctl(priv, req); break; @@ -2168,41 +888,11 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) break; case WLAN_SETNONE_GETONEINT: - switch ((int)req->ifr_data) { - case WLANGETBCNAVG: - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->bcn_avg_factor; - break; - + switch (wrq->u.param.value) { case WLANGETREGION: pdata = (int *)wrq->u.name; *pdata = (int)adapter->regioncode; break; - - case WLAN_GET_LISTEN_INTERVAL: - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->listeninterval; - break; - - case WLAN_GET_LINKMODE: - req->ifr_data = (char *)((u32) adapter->linkmode); - break; - - case WLAN_GET_RADIOMODE: - req->ifr_data = (char *)((u32) adapter->radiomode); - break; - - case WLAN_GET_DEBUGMODE: - req->ifr_data = (char *)((u32) adapter->debugmode); - break; - - case WLAN_GET_MULTIPLE_DTIM: - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->multipledtim; - break; - case WLAN_GET_TX_RATE: - ret = wlan_get_txrate_ioctl(priv, req); - break; case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */ ret = wlan_fwt_cleanup_ioctl(priv, req); break; @@ -2222,196 +912,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) break; - case WLANGETLOG: - ret = wlan_do_getlog_ioctl(priv, wrq); - break; - case WLAN_SET_GET_SIXTEEN_INT: switch ((int)wrq->u.data.flags) { - case WLAN_TPCCFG: - { - int data[5]; - struct cmd_ds_802_11_tpc_cfg cfg; - memset(&cfg, 0, sizeof(cfg)); - if ((wrq->u.data.length > 1) - && (wrq->u.data.length != 5)) - return -1; - - if (wrq->u.data.length == 0) { - cfg.action = - cpu_to_le16 - (cmd_act_get); - } else { - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * 5)) { - lbs_pr_debug(1, - "Copy from user failed\n"); - return -EFAULT; - } - - cfg.action = - cpu_to_le16 - (cmd_act_set); - cfg.enable = data[0]; - cfg.usesnr = data[1]; - cfg.P0 = data[2]; - cfg.P1 = data[3]; - cfg.P2 = data[4]; - } - - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_tpc_cfg, - 0, - cmd_option_waitforrsp, - 0, (void *)&cfg); - - data[0] = cfg.enable; - data[1] = cfg.usesnr; - data[2] = cfg.P0; - data[3] = cfg.P1; - data[4] = cfg.P2; - if (copy_to_user - (wrq->u.data.pointer, data, - sizeof(int) * 5)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = 5; - } - break; - - case WLAN_POWERCFG: - { - int data[4]; - struct cmd_ds_802_11_pwr_cfg cfg; - memset(&cfg, 0, sizeof(cfg)); - if ((wrq->u.data.length > 1) - && (wrq->u.data.length != 4)) - return -1; - if (wrq->u.data.length == 0) { - cfg.action = - cpu_to_le16 - (cmd_act_get); - } else { - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * 4)) { - lbs_pr_debug(1, - "Copy from user failed\n"); - return -EFAULT; - } - - cfg.action = - cpu_to_le16 - (cmd_act_set); - cfg.enable = data[0]; - cfg.PA_P0 = data[1]; - cfg.PA_P1 = data[2]; - cfg.PA_P2 = data[3]; - } - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_pwr_cfg, - 0, - cmd_option_waitforrsp, - 0, (void *)&cfg); - data[0] = cfg.enable; - data[1] = cfg.PA_P0; - data[2] = cfg.PA_P1; - data[3] = cfg.PA_P2; - if (copy_to_user - (wrq->u.data.pointer, data, - sizeof(int) * 4)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = 4; - } - break; - case WLAN_AUTO_FREQ_SET: - { - int data[3]; - struct cmd_ds_802_11_afc afc; - memset(&afc, 0, sizeof(afc)); - if (wrq->u.data.length != 3) - return -1; - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * 3)) { - lbs_pr_debug(1, "Copy from user failed\n"); - return -EFAULT; - } - afc.afc_auto = data[0]; - - if (afc.afc_auto != 0) { - afc.threshold = data[1]; - afc.period = data[2]; - } else { - afc.timing_offset = data[1]; - afc.carrier_offset = data[2]; - } - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_set_afc, - 0, - cmd_option_waitforrsp, - 0, (void *)&afc); - } - break; - case WLAN_AUTO_FREQ_GET: - { - int data[3]; - struct cmd_ds_802_11_afc afc; - memset(&afc, 0, sizeof(afc)); - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_get_afc, - 0, - cmd_option_waitforrsp, - 0, (void *)&afc); - data[0] = afc.afc_auto; - data[1] = afc.timing_offset; - data[2] = afc.carrier_offset; - if (copy_to_user - (wrq->u.data.pointer, data, - sizeof(int) * 3)) { - lbs_pr_debug(1, "Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = 3; - } - break; - case WLAN_SCANPROBES: - { - int data; - if (wrq->u.data.length > 0) { - if (copy_from_user - (&data, wrq->u.data.pointer, - sizeof(int))) { - lbs_pr_debug(1, - "Copy from user failed\n"); - return -EFAULT; - } - - adapter->scanprobes = data; - } else { - data = adapter->scanprobes; - if (copy_to_user - (wrq->u.data.pointer, &data, - sizeof(int))) { - lbs_pr_debug(1, - "Copy to user failed\n"); - return -EFAULT; - } - } - wrq->u.data.length = 1; - } - break; case WLAN_LED_GPIO_CTRL: { int i; @@ -2475,17 +977,6 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) wrq->u.data.length = gpio->header.len; } break; - case WLAN_ADAPT_RATESET: - ret = wlan_adapt_rateset(priv, wrq); - break; - case WLAN_INACTIVITY_TIMEOUT: - ret = wlan_inactivity_timeout(priv, wrq); - break; - case WLANSNR: - ret = wlan_get_snr(priv, wrq); - break; - case WLAN_GET_RXINFO: - ret = wlan_get_rxinfo(priv, wrq); } break; diff --git a/trunk/drivers/net/wireless/libertas/join.c b/trunk/drivers/net/wireless/libertas/join.c index 11682cbe752b..d4926b83e145 100644 --- a/trunk/drivers/net/wireless/libertas/join.c +++ b/trunk/drivers/net/wireless/libertas/join.c @@ -15,6 +15,8 @@ #include "join.h" #include "dev.h" +#define AD_HOC_CAP_PRIVACY_ON 1 + /** * @brief This function finds out the common rates between rate1 and rate2. * @@ -85,7 +87,7 @@ int libertas_send_deauth(wlan_private * priv) wlan_adapter *adapter = priv->adapter; int ret = 0; - if (adapter->inframode == wlan802_11infrastructure && + if (adapter->mode == IW_MODE_INFRA && adapter->connect_status == libertas_connected) ret = libertas_send_deauthentication(priv); else @@ -94,20 +96,6 @@ int libertas_send_deauth(wlan_private * priv) return ret; } -int libertas_do_adhocstop_ioctl(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - int ret = 0; - - if (adapter->inframode == wlan802_11ibss && - adapter->connect_status == libertas_connected) - ret = libertas_stop_adhoc_network(priv); - else - ret = -ENOTSUPP; - - return ret; -} - /** * @brief Associate to a specific BSS discovered in a scan * @@ -207,8 +195,7 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs /* check if the requested SSID is already joined */ if (adapter->curbssparams.ssid.ssidlength && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid) - && (adapter->curbssparams.bssdescriptor.inframode == - wlan802_11ibss)) { + && (adapter->mode == IW_MODE_ADHOC)) { lbs_pr_debug(1, "ADHOC_J_CMD: New ad-hoc SSID is the same as current, " @@ -260,130 +247,6 @@ int libertas_send_deauthentication(wlan_private * priv) 0, cmd_option_waitforrsp, 0, NULL); } -/** - * @brief Set Idle Off - * - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -int libertas_idle_off(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - int ret = 0; - const u8 zeromac[] = { 0, 0, 0, 0, 0, 0 }; - int i; - - ENTER(); - - if (adapter->connect_status == libertas_disconnected) { - if (adapter->inframode == wlan802_11infrastructure) { - if (memcmp(adapter->previousbssid, zeromac, - sizeof(zeromac)) != 0) { - - lbs_pr_debug(1, "Previous SSID = %s\n", - adapter->previousssid.ssid); - lbs_pr_debug(1, "Previous BSSID = " - "%02x:%02x:%02x:%02x:%02x:%02x:\n", - adapter->previousbssid[0], - adapter->previousbssid[1], - adapter->previousbssid[2], - adapter->previousbssid[3], - adapter->previousbssid[4], - adapter->previousbssid[5]); - - i = libertas_find_SSID_in_list(adapter, - &adapter->previousssid, - adapter->previousbssid, - adapter->inframode); - - if (i < 0) { - libertas_send_specific_BSSID_scan(priv, - adapter-> - previousbssid, - 1); - i = libertas_find_SSID_in_list(adapter, - &adapter-> - previousssid, - adapter-> - previousbssid, - adapter-> - inframode); - } - - if (i < 0) { - /* If the BSSID could not be found, try just the SSID */ - i = libertas_find_SSID_in_list(adapter, - &adapter-> - previousssid, NULL, - adapter-> - inframode); - } - - if (i < 0) { - libertas_send_specific_SSID_scan(priv, - &adapter-> - previousssid, - 1); - i = libertas_find_SSID_in_list(adapter, - &adapter-> - previousssid, NULL, - adapter-> - inframode); - } - - if (i >= 0) { - ret = - wlan_associate(priv, - &adapter-> - scantable[i]); - } - } - } else if (adapter->inframode == wlan802_11ibss) { - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_ad_hoc_start, - 0, - cmd_option_waitforrsp, - 0, &adapter->previousssid); - } - } - /* else it is connected */ - - lbs_pr_debug(1, "\nwlanidle is off"); - LEAVE(); - return ret; -} - -/** - * @brief Set Idle On - * - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -int libertas_idle_on(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - int ret = 0; - - if (adapter->connect_status == libertas_connected) { - if (adapter->inframode == wlan802_11infrastructure) { - lbs_pr_debug(1, "Previous SSID = %s\n", - adapter->previousssid.ssid); - memmove(&adapter->previousssid, - &adapter->curbssparams.ssid, - sizeof(struct WLAN_802_11_SSID)); - libertas_send_deauth(priv); - - } else if (adapter->inframode == wlan802_11ibss) { - ret = libertas_stop_adhoc_network(priv); - } - - } - - lbs_pr_debug(1, "\nwlanidle is on"); - - return ret; -} - /** * @brief This function prepares command of authenticate. * @@ -398,22 +261,39 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, void *pdata_buf) { wlan_adapter *adapter = priv->adapter; - struct cmd_ds_802_11_authenticate *pauthenticate = - &cmd->params.auth; + struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; + int ret = -1; u8 *bssid = pdata_buf; cmd->command = cpu_to_le16(cmd_802_11_authenticate); - cmd->size = - cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) - + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) + + S_DS_GEN); + + /* translate auth mode to 802.11 defined wire value */ + switch (adapter->secinfo.auth_mode) { + case IW_AUTH_ALG_OPEN_SYSTEM: + pauthenticate->authtype = 0x00; + break; + case IW_AUTH_ALG_SHARED_KEY: + pauthenticate->authtype = 0x01; + break; + case IW_AUTH_ALG_LEAP: + pauthenticate->authtype = 0x80; + break; + default: + lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n", + adapter->secinfo.auth_mode); + goto out; + } - pauthenticate->authtype = adapter->secinfo.authmode; memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); + ret = 0; - return 0; +out: + return ret; } int libertas_cmd_80211_deauthenticate(wlan_private * priv, @@ -550,7 +430,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len); /* set IBSS field */ - if (pbssdesc->inframode == wlan802_11infrastructure) { + if (pbssdesc->mode == IW_MODE_INFRA) { #define CAPINFO_ESS_MODE 1 passo->capinfo.ess = CAPINFO_ESS_MODE; } @@ -624,7 +504,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, /* set the BSS type */ adhs->bsstype = cmd_bss_type_ibss; - pbssdesc->inframode = wlan802_11ibss; + pbssdesc->mode = IW_MODE_ADHOC; adhs->beaconperiod = adapter->beaconperiod; /* set Physical param set */ @@ -666,15 +546,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time); /* set up privacy in adapter->scantable[i] */ - if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) { - -#define AD_HOC_CAP_PRIVACY_ON 1 - lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus set, privacy to WEP\n"); + if (adapter->secinfo.wep_enabled) { + lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n"); pbssdesc->privacy = wlan802_11privfilter8021xWEP; adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON; } else { - lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus NOT set, Setting " - "privacy to ACCEPT ALL\n"); + lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n"); pbssdesc->privacy = wlan802_11privfilteracceptall; } @@ -786,9 +663,6 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, padhocjoin->bssdescriptor.BSSID[5], padhocjoin->bssdescriptor.SSID); - lbs_pr_debug(1, "ADHOC_J_CMD: Data Rate = %x\n", - (u32) padhocjoin->bssdescriptor.datarates); - /* failtimeout */ padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT); @@ -832,7 +706,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow = cpu_to_le16(pbssdesc->atimwindow); - if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) { + if (adapter->secinfo.wep_enabled) { padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON; } diff --git a/trunk/drivers/net/wireless/libertas/join.h b/trunk/drivers/net/wireless/libertas/join.h index 8efa2455af9a..115f5a8ba346 100644 --- a/trunk/drivers/net/wireless/libertas/join.h +++ b/trunk/drivers/net/wireless/libertas/join.h @@ -1,6 +1,3 @@ -/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */ - /** * Interface for the wlan infrastructure and adhoc join routines * @@ -40,10 +37,6 @@ extern int libertas_ret_80211_disassociate(wlan_private * priv, extern int libertas_ret_80211_associate(wlan_private * priv, struct cmd_ds_command *resp); -extern int libertas_idle_on(wlan_private * priv); -extern int libertas_idle_off(wlan_private * priv); - -extern int libertas_do_adhocstop_ioctl(wlan_private * priv); extern int libertas_reassociation_thread(void *data); struct WLAN_802_11_SSID; diff --git a/trunk/drivers/net/wireless/libertas/main.c b/trunk/drivers/net/wireless/libertas/main.c index dcbf102a057e..b9b25ce65919 100644 --- a/trunk/drivers/net/wireless/libertas/main.c +++ b/trunk/drivers/net/wireless/libertas/main.c @@ -21,6 +21,13 @@ #include "debugfs.h" #include "assoc.h" +#define DRIVER_RELEASE_VERSION "320.p0" +const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION +#ifdef DEBUG + "-dbg" +#endif + ""; + #ifdef ENABLE_PM static struct pm_dev *wlan_pm_dev = NULL; #endif diff --git a/trunk/drivers/net/wireless/libertas/rx.c b/trunk/drivers/net/wireless/libertas/rx.c index 7e3f78f092dc..d17924f764e5 100644 --- a/trunk/drivers/net/wireless/libertas/rx.c +++ b/trunk/drivers/net/wireless/libertas/rx.c @@ -210,7 +210,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) goto done; } - lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n", + lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, @@ -364,7 +364,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) priv->stats.rx_errors++; } - lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n", + lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); /* create the exported radio header */ diff --git a/trunk/drivers/net/wireless/libertas/scan.c b/trunk/drivers/net/wireless/libertas/scan.c index e18706238951..3c0b1a2a1727 100644 --- a/trunk/drivers/net/wireless/libertas/scan.c +++ b/trunk/drivers/net/wireless/libertas/scan.c @@ -1,6 +1,3 @@ -/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */ - /** * Functions implementing wlan scan IOCTL and firmware command APIs * @@ -87,118 +84,95 @@ * * @return Index in scantable, or error code if negative */ -static int is_network_compatible(wlan_adapter * adapter, int index, int mode) +static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode) { ENTER(); - if (adapter->scantable[index].inframode == mode) { - if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled + if (adapter->scantable[index].mode == mode) { + if ( !adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled - && adapter->scantable[index].wpa_supplicant.wpa_ie[0] != - WPA_IE - && adapter->scantable[index].wpa2_supplicant.wpa_ie[0] != - WPA2_IE && adapter->secinfo.Encryptionmode == CIPHER_NONE + && adapter->scantable[index].wpa_ie[0] != WPA_IE + && adapter->scantable[index].rsn_ie[0] != WPA2_IE && !adapter->scantable[index].privacy) { /* no security */ LEAVE(); return index; - } else if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled + } else if ( adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled && adapter->scantable[index].privacy) { /* static WEP enabled */ LEAVE(); return index; - } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled + } else if ( !adapter->secinfo.wep_enabled && adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled - && (adapter->scantable[index].wpa_supplicant. - wpa_ie[0] - == WPA_IE) + && (adapter->scantable[index].wpa_ie[0] == WPA_IE) /* privacy bit may NOT be set in some APs like LinkSys WRT54G && adapter->scantable[index].privacy */ ) { /* WPA enabled */ - lbs_pr_debug(1, + lbs_pr_debug(1, "is_network_compatible() WPA: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x " + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " "privacy=%#x\n", index, - adapter->scantable[index].wpa_supplicant. - wpa_ie[0], - adapter->scantable[index].wpa2_supplicant. - wpa_ie[0], - (adapter->secinfo.WEPstatus == - wlan802_11WEPenabled) ? "e" : "d", - (adapter->secinfo.WPAenabled) ? "e" : "d", - (adapter->secinfo.WPA2enabled) ? "e" : "d", - adapter->secinfo.Encryptionmode, + adapter->scantable[index].wpa_ie[0], + adapter->scantable[index].rsn_ie[0], + adapter->secinfo.wep_enabled ? "e" : "d", + adapter->secinfo.WPAenabled ? "e" : "d", + adapter->secinfo.WPA2enabled ? "e" : "d", adapter->scantable[index].privacy); LEAVE(); return index; - } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled + } else if ( !adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && adapter->secinfo.WPA2enabled - && (adapter->scantable[index].wpa2_supplicant. - wpa_ie[0] - == WPA2_IE) + && (adapter->scantable[index].rsn_ie[0] == WPA2_IE) /* privacy bit may NOT be set in some APs like LinkSys WRT54G && adapter->scantable[index].privacy */ ) { /* WPA2 enabled */ - lbs_pr_debug(1, + lbs_pr_debug(1, "is_network_compatible() WPA2: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x " + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " "privacy=%#x\n", index, - adapter->scantable[index].wpa_supplicant. - wpa_ie[0], - adapter->scantable[index].wpa2_supplicant. - wpa_ie[0], - (adapter->secinfo.WEPstatus == - wlan802_11WEPenabled) ? "e" : "d", - (adapter->secinfo.WPAenabled) ? "e" : "d", - (adapter->secinfo.WPA2enabled) ? "e" : "d", - adapter->secinfo.Encryptionmode, + adapter->scantable[index].wpa_ie[0], + adapter->scantable[index].rsn_ie[0], + adapter->secinfo.wep_enabled ? "e" : "d", + adapter->secinfo.WPAenabled ? "e" : "d", + adapter->secinfo.WPA2enabled ? "e" : "d", adapter->scantable[index].privacy); LEAVE(); return index; - } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled + } else if ( !adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled - && (adapter->scantable[index].wpa_supplicant. - wpa_ie[0] - != WPA_IE) - && (adapter->scantable[index].wpa2_supplicant. - wpa_ie[0] - != WPA2_IE) - && adapter->secinfo.Encryptionmode != CIPHER_NONE + && (adapter->scantable[index].wpa_ie[0] != WPA_IE) + && (adapter->scantable[index].rsn_ie[0] != WPA2_IE) && adapter->scantable[index].privacy) { /* dynamic WEP enabled */ - lbs_pr_debug(1, + lbs_pr_debug(1, "is_network_compatible() dynamic WEP: index=%d " - "wpa_ie=%#x wpa2_ie=%#x Encmode=%#x privacy=%#x\n", + "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n", index, - adapter->scantable[index].wpa_supplicant. - wpa_ie[0], - adapter->scantable[index].wpa2_supplicant. - wpa_ie[0], adapter->secinfo.Encryptionmode, + adapter->scantable[index].wpa_ie[0], + adapter->scantable[index].rsn_ie[0], adapter->scantable[index].privacy); LEAVE(); return index; } /* security doesn't match */ - lbs_pr_debug(1, + lbs_pr_debug(1, "is_network_compatible() FAILED: index=%d wpa_ie=%#x " - "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x privacy=%#x\n", + "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n", index, - adapter->scantable[index].wpa_supplicant.wpa_ie[0], - adapter->scantable[index].wpa2_supplicant.wpa_ie[0], - (adapter->secinfo.WEPstatus == - wlan802_11WEPenabled) ? "e" : "d", - (adapter->secinfo.WPAenabled) ? "e" : "d", - (adapter->secinfo.WPA2enabled) ? "e" : "d", - adapter->secinfo.Encryptionmode, + adapter->scantable[index].wpa_ie[0], + adapter->scantable[index].rsn_ie[0], + adapter->secinfo.wep_enabled ? "e" : "d", + adapter->secinfo.WPAenabled ? "e" : "d", + adapter->secinfo.WPA2enabled ? "e" : "d", adapter->scantable[index].privacy); LEAVE(); return -ECONNREFUSED; @@ -924,8 +898,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, u8 founddatarateie; int bytesleftforcurrentbeacon; - struct WPA_SUPPLICANT *pwpa_supplicant; - struct WPA_SUPPLICANT *pwpa2_supplicant; struct IE_WPA *pIe; const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 }; @@ -962,9 +934,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, bytesleftforcurrentbeacon = beaconsize; - pwpa_supplicant = &pBSSEntry->wpa_supplicant; - pwpa2_supplicant = &pBSSEntry->wpa2_supplicant; - memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN); lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n", pBSSEntry->macaddress[0], pBSSEntry->macaddress[1], @@ -1027,9 +996,9 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, } if (pcap->ibss == 1) { - pBSSEntry->inframode = wlan802_11ibss; + pBSSEntry->mode = IW_MODE_ADHOC; } else { - pBSSEntry->inframode = wlan802_11infrastructure; + pBSSEntry->mode = IW_MODE_INFRA; } /* process variable IE */ @@ -1116,7 +1085,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, sizeof(pcountryinfo->countrycode) || pcountryinfo->len > 254) { lbs_pr_debug(1, "InterpretIE: 11D- Err " - "CountryInfo len =%d min=%d max=254\n", + "CountryInfo len =%d min=%zd max=254\n", pcountryinfo->len, sizeof(pcountryinfo->countrycode)); LEAVE(); @@ -1160,27 +1129,27 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry, #define IE_ID_LEN_FIELDS_BYTES 2 pIe = (struct IE_WPA *)pcurrentptr; - if (!memcmp(pIe->oui, oui01, sizeof(oui01))) { - pwpa_supplicant->wpa_ie_len - = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES, - sizeof(pwpa_supplicant->wpa_ie)); - memcpy(pwpa_supplicant->wpa_ie, - pcurrentptr, - pwpa_supplicant->wpa_ie_len); - lbs_dbg_hex("InterpretIE: Resp WPA_IE", - pwpa_supplicant->wpa_ie, elemlen); - } + if (memcmp(pIe->oui, oui01, sizeof(oui01))) + break; + + pBSSEntry->wpa_ie_len = min_t(size_t, + elemlen + IE_ID_LEN_FIELDS_BYTES, + sizeof(pBSSEntry->wpa_ie)); + memcpy(pBSSEntry->wpa_ie, pcurrentptr, + pBSSEntry->wpa_ie_len); + lbs_dbg_hex("InterpretIE: Resp WPA_IE", + pBSSEntry->wpa_ie, elemlen); break; case WPA2_IE: pIe = (struct IE_WPA *)pcurrentptr; - pwpa2_supplicant->wpa_ie_len - = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES, - sizeof(pwpa2_supplicant->wpa_ie)); - memcpy(pwpa2_supplicant->wpa_ie, - pcurrentptr, pwpa2_supplicant->wpa_ie_len); + pBSSEntry->rsn_ie_len = min_t(size_t, + elemlen + IE_ID_LEN_FIELDS_BYTES, + sizeof(pBSSEntry->rsn_ie)); + memcpy(pBSSEntry->rsn_ie, pcurrentptr, + pBSSEntry->rsn_ie_len); lbs_dbg_hex("InterpretIE: Resp WPA2_IE", - pwpa2_supplicant->wpa_ie, elemlen); + pBSSEntry->rsn_ie, elemlen); break; case TIM: break; @@ -1227,7 +1196,7 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s * * @return index in BSSID list, or error return code (< 0) */ -int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode) +int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode) { int ret = -ENETUNREACH; int i; @@ -1247,8 +1216,8 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode) for (i = 0; ret < 0 && i < adapter->numinscantable; i++) { if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) { switch (mode) { - case wlan802_11infrastructure: - case wlan802_11ibss: + case IW_MODE_INFRA: + case IW_MODE_ADHOC: ret = is_network_compatible(adapter, i, mode); break; default: @@ -1272,7 +1241,7 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode) * @return index in BSSID list */ int libertas_find_SSID_in_list(wlan_adapter * adapter, - struct WLAN_802_11_SSID *ssid, u8 * bssid, int mode) + struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode) { int net = -ENETUNREACH; u8 bestrssi = 0; @@ -1287,8 +1256,8 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter, !memcmp(adapter->scantable[i]. macaddress, bssid, ETH_ALEN))) { switch (mode) { - case wlan802_11infrastructure: - case wlan802_11ibss: + case IW_MODE_INFRA: + case IW_MODE_ADHOC: j = is_network_compatible(adapter, i, mode); if (j >= 0) { @@ -1311,7 +1280,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter, } } break; - case wlan802_11autounknown: + case IW_MODE_AUTO: default: if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) { @@ -1338,8 +1307,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter, * * @return index in BSSID list */ -int libertas_find_best_SSID_in_list(wlan_adapter * adapter, - enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode) +int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode) { int bestnet = -ENETUNREACH; u8 bestrssi = 0; @@ -1351,8 +1319,8 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, for (i = 0; i < adapter->numinscantable; i++) { switch (mode) { - case wlan802_11infrastructure: - case wlan802_11ibss: + case IW_MODE_INFRA: + case IW_MODE_ADHOC: if (is_network_compatible(adapter, i, mode) >= 0) { if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) { @@ -1363,7 +1331,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, } } break; - case wlan802_11autounknown: + case IW_MODE_AUTO: default: if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) { bestrssi = @@ -1388,8 +1356,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, */ int libertas_find_best_network_SSID(wlan_private * priv, struct WLAN_802_11_SSID *pSSID, - enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode, - enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode) + u8 preferred_mode, u8 *out_mode) { wlan_adapter *adapter = priv->adapter; int ret = 0; @@ -1414,7 +1381,7 @@ int libertas_find_best_network_SSID(wlan_private * priv, preqbssid = &adapter->scantable[i]; memcpy(pSSID, &preqbssid->ssid, sizeof(struct WLAN_802_11_SSID)); - *out_mode = preqbssid->inframode; + *out_mode = preqbssid->mode; if (!pSSID->ssidlength) { ret = -1; @@ -1584,7 +1551,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, for (i = 0; i < adapter->numinscantable; i++) { if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) { lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p " - "MAX_SCAN_CELL_SIZE=%d\n", + "MAX_SCAN_CELL_SIZE=%zd\n", i, current_ev, end_buf, MAX_SCAN_CELL_SIZE); break; } @@ -1632,7 +1599,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, //Add mode iwe.cmd = SIOCGIWMODE; - iwe.u.mode = adapter->scantable[i].inframode + 1; + iwe.u.mode = adapter->scantable[i].mode; iwe.len = IW_EV_UINT_LEN; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len); @@ -1666,7 +1633,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, iwe.u.qual.noise = CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]); } - if ((adapter->inframode == wlan802_11ibss) && + if ((adapter->mode == IW_MODE_ADHOC) && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &adapter->scantable[i].ssid) && adapter->adhoccreate) { @@ -1731,7 +1698,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, end_buf, &iwe, iwe.len); } - if ((adapter->scantable[i].inframode == wlan802_11ibss) + if ((adapter->scantable[i].mode == IW_MODE_ADHOC) && !libertas_SSID_cmp(&adapter->curbssparams.ssid, &adapter->scantable[i].ssid) && adapter->adhoccreate) { @@ -1745,30 +1712,24 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, /* Add new value to event */ current_val = current_ev + IW_EV_LCP_LEN; - if (adapter->scantable[i].wpa2_supplicant.wpa_ie[0] == WPA2_IE) { + if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) { memset(&iwe, 0, sizeof(iwe)); memset(buf, 0, sizeof(buf)); - memcpy(buf, adapter->scantable[i]. - wpa2_supplicant.wpa_ie, - adapter->scantable[i].wpa2_supplicant. - wpa_ie_len); + memcpy(buf, adapter->scantable[i].rsn_ie, + adapter->scantable[i].rsn_ie_len); iwe.cmd = IWEVGENIE; - iwe.u.data.length = adapter->scantable[i]. - wpa2_supplicant.wpa_ie_len; + iwe.u.data.length = adapter->scantable[i].rsn_ie_len; iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); } - if (adapter->scantable[i].wpa_supplicant.wpa_ie[0] == WPA_IE) { + if (adapter->scantable[i].wpa_ie[0] == WPA_IE) { memset(&iwe, 0, sizeof(iwe)); memset(buf, 0, sizeof(buf)); - memcpy(buf, adapter->scantable[i]. - wpa_supplicant.wpa_ie, - adapter->scantable[i].wpa_supplicant. - wpa_ie_len); + memcpy(buf, adapter->scantable[i].wpa_ie, + adapter->scantable[i].wpa_ie_len); iwe.cmd = IWEVGENIE; - iwe.u.data.length = adapter->scantable[i]. - wpa_supplicant.wpa_ie_len; + iwe.u.data.length = adapter->scantable[i].wpa_ie_len; iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); diff --git a/trunk/drivers/net/wireless/libertas/scan.h b/trunk/drivers/net/wireless/libertas/scan.h index d93aa7fa44fd..405f4f0fe575 100644 --- a/trunk/drivers/net/wireless/libertas/scan.h +++ b/trunk/drivers/net/wireless/libertas/scan.h @@ -1,6 +1,3 @@ -/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ -/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */ - /** * Interface for the wlan network scan routines * @@ -10,6 +7,7 @@ #ifndef _WLAN_SCAN_H #define _WLAN_SCAN_H +#include #include "hostcmd.h" /** @@ -155,7 +153,7 @@ struct bss_descriptor { u32 atimwindow; - enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode; + u8 mode; u8 libertas_supported_rates[WLAN_SUPPORTED_RATES]; int extra_ie; @@ -170,22 +168,22 @@ struct bss_descriptor { struct ieeetypes_countryinfofullset countryinfo; - struct WPA_SUPPLICANT wpa_supplicant; - struct WPA_SUPPLICANT wpa2_supplicant; - + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; }; extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2); extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid, - u8 * bssid, int mode); -int libertas_find_best_SSID_in_list(wlan_adapter * adapter, enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode); -extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode); + u8 * bssid, u8 mode); +int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode); +extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode); int libertas_find_best_network_SSID(wlan_private * priv, struct WLAN_802_11_SSID *pSSID, - enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode, - enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode); + u8 preferred_mode, u8 *out_mode); extern int libertas_send_specific_SSID_scan(wlan_private * priv, struct WLAN_802_11_SSID *prequestedssid, diff --git a/trunk/drivers/net/wireless/libertas/tx.c b/trunk/drivers/net/wireless/libertas/tx.c index 82d06223043e..d4b13478c9a7 100644 --- a/trunk/drivers/net/wireless/libertas/tx.c +++ b/trunk/drivers/net/wireless/libertas/tx.c @@ -78,7 +78,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) min_t(unsigned int, skb->len, 100)); if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) { - lbs_pr_debug(1, "Tx error: Bad skb length %d : %d\n", + lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n", skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE); ret = -1; goto done; diff --git a/trunk/drivers/net/wireless/libertas/version.h b/trunk/drivers/net/wireless/libertas/version.h index e86f65ae79b8..8b137891791f 100644 --- a/trunk/drivers/net/wireless/libertas/version.h +++ b/trunk/drivers/net/wireless/libertas/version.h @@ -1,8 +1 @@ -#define DRIVER_RELEASE_VERSION "320.p0" -const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION -#ifdef DEBUG - "-dbg" -#endif - ""; - diff --git a/trunk/drivers/net/wireless/libertas/wext.c b/trunk/drivers/net/wireless/libertas/wext.c index 4a52336bc0f6..69f52b6e59c8 100644 --- a/trunk/drivers/net/wireless/libertas/wext.c +++ b/trunk/drivers/net/wireless/libertas/wext.c @@ -17,7 +17,6 @@ #include "defs.h" #include "dev.h" #include "join.h" -#include "version.h" #include "wext.h" #include "assoc.h" @@ -233,7 +232,7 @@ static int changeadhocchannel(wlan_private * priv, int channel) // find out the BSSID that matches the current SSID i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL, - wlan802_11ibss); + IW_MODE_ADHOC); if (i >= 0) { lbs_pr_debug(1, "SSID found at %d in List," @@ -316,13 +315,11 @@ static int get_active_data_rates(wlan_adapter * adapter, ENTER(); if (adapter->connect_status != libertas_connected) { - if (adapter->inframode == wlan802_11infrastructure) { - //Infra. mode + if (adapter->mode == IW_MODE_INFRA) { lbs_pr_debug(1, "Infra\n"); k = copyrates(rates, k, libertas_supported_rates, sizeof(libertas_supported_rates)); } else { - //ad-hoc mode lbs_pr_debug(1, "Adhoc G\n"); k = copyrates(rates, k, libertas_adhoc_rates_g, sizeof(libertas_adhoc_rates_g)); @@ -586,20 +583,7 @@ static int wlan_get_mode(struct net_device *dev, ENTER(); - switch (adapter->inframode) { - case wlan802_11ibss: - *uwrq = IW_MODE_ADHOC; - break; - - case wlan802_11infrastructure: - *uwrq = IW_MODE_INFRA; - break; - - default: - case wlan802_11autounknown: - *uwrq = IW_MODE_AUTO; - break; - } + *uwrq = adapter->mode; LEAVE(); return 0; @@ -1002,148 +986,17 @@ static const struct iw_priv_args wlan_private_args[] = { /* * { cmd, set_args, get_args, name } */ - { - WLANSCAN_TYPE, - IW_PRIV_TYPE_CHAR | 8, - IW_PRIV_TYPE_CHAR | 8, - "scantype"}, - - { - WLAN_SETINT_GETINT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - ""}, - { - WLANNF, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getNF"}, - { - WLANRSSI, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getRSSI"}, - { - WLANENABLE11D, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "enable11d"}, - { - WLANADHOCGRATE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "adhocgrate"}, - - { - WLAN_SUBCMD_SET_PRESCAN, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "prescan"}, - { - WLAN_SETONEINT_GETONEINT, - IW_PRIV_TYPE_INT | 1, - IW_PRIV_TYPE_INT | 1, - ""}, - { - WLAN_BEACON_INTERVAL, - IW_PRIV_TYPE_INT | 1, - IW_PRIV_TYPE_INT | 1, - "bcninterval"}, - { - WLAN_LISTENINTRVL, - IW_PRIV_TYPE_INT | 1, - IW_PRIV_TYPE_INT | 1, - "lolisteninter"}, - { - WLAN_TXCONTROL, - IW_PRIV_TYPE_INT | 1, - IW_PRIV_TYPE_INT | 1, - "txcontrol"}, - { - WLAN_NULLPKTINTERVAL, - IW_PRIV_TYPE_INT | 1, - IW_PRIV_TYPE_INT | 1, - "psnullinterval"}, /* Using iwpriv sub-command feature */ { WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, ""}, - - { - WLAN_SUBCMD_SETRXANTENNA, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setrxant"}, - { - WLAN_SUBCMD_SETTXANTENNA, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "settxant"}, - { - WLANSETAUTHALG, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "authalgs", - }, - { - WLANSET8021XAUTHALG, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "8021xauthalgs", - }, - { - WLANSETENCRYPTIONMODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "encryptionmode", - }, { WLANSETREGION, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "setregioncode"}, - { - WLAN_SET_LISTEN_INTERVAL, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setlisteninter"}, - { - WLAN_SET_MULTIPLE_DTIM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setmultipledtim"}, - { - WLAN_SET_ATIM_WINDOW, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "atimwindow"}, - { - WLANSETBCNAVG, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setbcnavg"}, - { - WLANSETDATAAVG, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setdataavg"}, - { - WLAN_SET_LINKMODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "linkmode"}, - { - WLAN_SET_RADIOMODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "radiomode"}, - { - WLAN_SET_DEBUGMODE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "debugmode"}, { WLAN_SUBCMD_MESH_SET_TTL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, @@ -1159,41 +1012,6 @@ static const struct iw_priv_args wlan_private_args[] = { IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getregioncode"}, - { - WLAN_GET_LISTEN_INTERVAL, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getlisteninter"}, - { - WLAN_GET_MULTIPLE_DTIM, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getmultipledtim"}, - { - WLAN_GET_TX_RATE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "gettxrate"}, - { - WLANGETBCNAVG, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getbcnavg"}, - { - WLAN_GET_LINKMODE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "get_linkmode"}, - { - WLAN_GET_RADIOMODE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "get_radiomode"}, - { - WLAN_GET_DEBUGMODE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "get_debugmode"}, { WLAN_SUBCMD_FWT_CLEANUP, IW_PRIV_TYPE_NONE, @@ -1209,61 +1027,11 @@ static const struct iw_priv_args wlan_private_args[] = { IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "mesh_get_ttl"}, - { - WLAN_SETNONE_GETTWELVE_CHAR, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | 12, - ""}, - { - WLAN_SUBCMD_GETRXANTENNA, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | 12, - "getrxant"}, - { - WLAN_SUBCMD_GETTXANTENNA, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | 12, - "gettxant"}, - { - WLAN_GET_TSF, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | 12, - "gettsf"}, { WLAN_SETNONE_GETNONE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_NONE, ""}, - { - WLANDEAUTH, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "deauth"}, - { - WLANADHOCSTOP, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "adhocstop"}, - { - WLANRADIOON, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "radioon"}, - { - WLANRADIOOFF, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "radiooff"}, - { - WLANWLANIDLEON, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "wlanidle-on"}, - { - WLANWLANIDLEOFF, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "wlanidle-off"}, { WLAN_SUBCMD_FWT_RESET, IW_PRIV_TYPE_NONE, @@ -1326,91 +1094,16 @@ static const struct iw_priv_args wlan_private_args[] = { IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | 128, "fwt_list_route"}, - { - WLANSCAN_MODE, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "scanmode"}, - { - WLAN_GET_ADHOC_STATUS, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "getadhocstatus"}, - { - WLAN_SETNONE_GETWORDCHAR, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | 128, - ""}, - { - WLANSETWPAIE, - IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 24, - IW_PRIV_TYPE_NONE, - "setwpaie"}, - { - WLANGETLOG, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE, - "getlog"}, { WLAN_SET_GET_SIXTEEN_INT, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, ""}, - { - WLAN_TPCCFG, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "tpccfg"}, - { - WLAN_POWERCFG, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "powercfg"}, - { - WLAN_AUTO_FREQ_SET, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "setafc"}, - { - WLAN_AUTO_FREQ_GET, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "getafc"}, - { - WLAN_SCANPROBES, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "scanprobes"}, { WLAN_LED_GPIO_CTRL, IW_PRIV_TYPE_INT | 16, IW_PRIV_TYPE_INT | 16, "ledgpio"}, - { - WLAN_ADAPT_RATESET, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "rateadapt"}, - { - WLAN_INACTIVITY_TIMEOUT, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "inactivityto"}, - { - WLANSNR, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "getSNR"}, - { - WLAN_GET_RATE, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "getrate"}, - { - WLAN_GET_RXINFO, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "getrxinfo"}, }; static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) @@ -1434,7 +1127,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) ENTER(); - priv->wstats.status = adapter->inframode; + priv->wstats.status = adapter->mode; /* If we're not associated, all quality values are meaningless */ if (adapter->connect_status != libertas_connected) @@ -1568,13 +1261,12 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, if (!cfp) { rc = -EINVAL; } else { - if (adapter->inframode == wlan802_11ibss) { + if (adapter->mode == IW_MODE_ADHOC) { rc = changeadhocchannel(priv, channel); /* If station is WEP enabled, send the * command to set WEP in firmware */ - if (adapter->secinfo.WEPstatus == - wlan802_11WEPenabled) { + if (adapter->secinfo.wep_enabled) { lbs_pr_debug(1, "set_freq: WEP enabled\n"); ret = libertas_prepare_and_send_command(priv, cmd_802_11_set_wep, @@ -1716,49 +1408,31 @@ static int wlan_set_mode(struct net_device *dev, wlan_private *priv = dev->priv; wlan_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; - enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode; ENTER(); - switch (*uwrq) { - case IW_MODE_ADHOC: - lbs_pr_debug(1, "Wanted mode is ad-hoc: current datarate=%#x\n", - adapter->datarate); - new_mode = wlan802_11ibss; - adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL; - break; - - case IW_MODE_INFRA: - lbs_pr_debug(1, "Wanted mode is Infrastructure\n"); - new_mode = wlan802_11infrastructure; - break; - - case IW_MODE_AUTO: - lbs_pr_debug(1, "Wanted mode is Auto\n"); - new_mode = wlan802_11autounknown; - break; - - default: - lbs_pr_debug(1, "Wanted mode is Unknown: 0x%x\n", *uwrq); - return -EINVAL; + if ( (*uwrq != IW_MODE_ADHOC) + && (*uwrq != IW_MODE_INFRA) + && (*uwrq != IW_MODE_AUTO)) { + lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq); + ret = -EINVAL; + goto out; } mutex_lock(&adapter->lock); assoc_req = wlan_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; + wlan_cancel_association_work(priv); } else { - assoc_req->mode = new_mode; - } - - if (ret == 0) { + assoc_req->mode = *uwrq; set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); wlan_postpone_association_work(priv); - } else { - wlan_cancel_association_work(priv); + lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq); } mutex_unlock(&adapter->lock); +out: LEAVE(); return ret; } @@ -1789,13 +1463,13 @@ static int wlan_get_encode(struct net_device *dev, dwrq->flags = 0; /* Authentication method */ - switch (adapter->secinfo.authmode) { - case wlan802_11authmodeopen: + switch (adapter->secinfo.auth_mode) { + case IW_AUTH_ALG_OPEN_SYSTEM: dwrq->flags = IW_ENCODE_OPEN; break; - case wlan802_11authmodeshared: - case wlan802_11authmodenetworkEAP: + case IW_AUTH_ALG_SHARED_KEY: + case IW_AUTH_ALG_LEAP: dwrq->flags = IW_ENCODE_RESTRICTED; break; default: @@ -1803,8 +1477,9 @@ static int wlan_get_encode(struct net_device *dev, break; } - if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled) - || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { + if ( adapter->secinfo.wep_enabled + || adapter->secinfo.WPAenabled + || adapter->secinfo.WPA2enabled) { dwrq->flags &= ~IW_ENCODE_DISABLED; } else { dwrq->flags |= IW_ENCODE_DISABLED; @@ -1818,8 +1493,7 @@ static int wlan_get_encode(struct net_device *dev, if (index < 0) index = adapter->wep_tx_keyidx; - if ((adapter->wep_keys[index].len) && - (adapter->secinfo.WEPstatus == wlan802_11WEPenabled)) { + if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) { memcpy(extra, adapter->wep_keys[index].key, adapter->wep_keys[index].len); dwrq->length = adapter->wep_keys[index].len; @@ -1903,7 +1577,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req, assoc_req->wep_tx_keyidx = index; } - assoc_req->secinfo.WEPstatus = wlan802_11WEPenabled; + assoc_req->secinfo.wep_enabled = 1; LEAVE(); return 0; @@ -1932,10 +1606,10 @@ static void disable_wep(struct assoc_request *assoc_req) int i; /* Set Open System auth mode */ - assoc_req->secinfo.authmode = wlan802_11authmodeopen; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; /* Clear WEP keys and mark WEP as disabled */ - assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled; + assoc_req->secinfo.wep_enabled = 0; for (i = 0; i < 4; i++) assoc_req->wep_keys[i].len = 0; @@ -1987,8 +1661,7 @@ static int wlan_set_encode(struct net_device *dev, /* If WEP isn't enabled, or if there is no key data but a valid * index, set the TX key. */ - if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled) - || (dwrq->length == 0 && !is_default)) + if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default)) set_tx_key = 1; ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); @@ -2001,9 +1674,9 @@ static int wlan_set_encode(struct net_device *dev, set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); if (dwrq->flags & IW_ENCODE_RESTRICTED) { - assoc_req->secinfo.authmode = wlan802_11authmodeshared; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { - assoc_req->secinfo.authmode = wlan802_11authmodeopen; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } out: @@ -2056,30 +1729,31 @@ static int wlan_get_encodeext(struct net_device *dev, if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && ext->alg != IW_ENCODE_ALG_WEP) { - if (index != 0 || adapter->inframode != wlan802_11infrastructure) + if (index != 0 || adapter->mode != IW_MODE_INFRA) goto out; } dwrq->flags = index + 1; memset(ext, 0, sizeof(*ext)); - if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) - && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) { + if ( !adapter->secinfo.wep_enabled + && !adapter->secinfo.WPAenabled + && !adapter->secinfo.WPA2enabled) { ext->alg = IW_ENCODE_ALG_NONE; ext->key_len = 0; dwrq->flags |= IW_ENCODE_DISABLED; } else { u8 *key = NULL; - if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled) + if ( adapter->secinfo.wep_enabled && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) { ext->alg = IW_ENCODE_ALG_WEP; ext->key_len = adapter->wep_keys[index].len; key = &adapter->wep_keys[index].key[0]; - } else if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) && - (adapter->secinfo.WPAenabled || - adapter->secinfo.WPA2enabled)) { + } else if ( !adapter->secinfo.wep_enabled + && (adapter->secinfo.WPAenabled || + adapter->secinfo.WPA2enabled)) { /* WPA */ ext->alg = IW_ENCODE_ALG_TKIP; ext->key_len = 0; @@ -2149,7 +1823,7 @@ static int wlan_set_encodeext(struct net_device *dev, /* If WEP isn't enabled, or if there is no key data but a valid * index, or if the set-TX-key flag was passed, set the TX key. */ - if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled) + if ( !assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default) || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) set_tx_key = 1; @@ -2161,11 +1835,9 @@ static int wlan_set_encodeext(struct net_device *dev, goto out; if (dwrq->flags & IW_ENCODE_RESTRICTED) { - assoc_req->secinfo.authmode = - wlan802_11authmodeshared; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->flags & IW_ENCODE_OPEN) { - assoc_req->secinfo.authmode = - wlan802_11authmodeopen; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } /* Mark the various WEP bits as modified */ @@ -2350,15 +2022,13 @@ static int wlan_set_auth(struct net_device *dev, } if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) { assoc_req->secinfo.WPAenabled = 1; - assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled; - assoc_req->secinfo.authmode = - wlan802_11authmodeopen; + assoc_req->secinfo.wep_enabled = 0; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) { assoc_req->secinfo.WPA2enabled = 1; - assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled; - assoc_req->secinfo.authmode = - wlan802_11authmodeopen; + assoc_req->secinfo.wep_enabled = 0; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } updated = 1; break; @@ -2376,14 +2046,11 @@ static int wlan_set_auth(struct net_device *dev, case IW_AUTH_80211_AUTH_ALG: if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) { - assoc_req->secinfo.authmode = - wlan802_11authmodeshared; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; } else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) { - assoc_req->secinfo.authmode = - wlan802_11authmodeopen; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } else if (dwrq->value & IW_AUTH_ALG_LEAP) { - assoc_req->secinfo.authmode = - wlan802_11authmodenetworkEAP; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP; } else { ret = -EINVAL; } @@ -2396,9 +2063,8 @@ static int wlan_set_auth(struct net_device *dev, !assoc_req->secinfo.WPA2enabled) { assoc_req->secinfo.WPAenabled = 1; assoc_req->secinfo.WPA2enabled = 1; - assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled; - assoc_req->secinfo.authmode = - wlan802_11authmodeopen; + assoc_req->secinfo.wep_enabled = 0; + assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; } } else { assoc_req->secinfo.WPAenabled = 0; @@ -2455,19 +2121,7 @@ static int wlan_get_auth(struct net_device *dev, break; case IW_AUTH_80211_AUTH_ALG: - switch (adapter->secinfo.authmode) { - case wlan802_11authmodeshared: - dwrq->value = IW_AUTH_ALG_SHARED_KEY; - break; - case wlan802_11authmodeopen: - dwrq->value = IW_AUTH_ALG_OPEN_SYSTEM; - break; - case wlan802_11authmodenetworkEAP: - dwrq->value = IW_AUTH_ALG_LEAP; - break; - default: - break; - } + dwrq->value = adapter->secinfo.auth_mode; break; case IW_AUTH_WPA_ENABLED: diff --git a/trunk/drivers/net/wireless/libertas/wext.h b/trunk/drivers/net/wireless/libertas/wext.h index 39f367c38d90..15cfaaf0797f 100644 --- a/trunk/drivers/net/wireless/libertas/wext.h +++ b/trunk/drivers/net/wireless/libertas/wext.h @@ -10,88 +10,22 @@ /** PRIVATE CMD ID */ #define WLANIOCTL SIOCIWFIRSTPRIV -#define WLANSETWPAIE (WLANIOCTL + 0) - -#define WLAN_SETINT_GETINT (WLANIOCTL + 7) -#define WLANNF 1 -#define WLANRSSI 2 -#define WLANENABLE11D 5 -#define WLANADHOCGRATE 6 -#define WLAN_SUBCMD_SET_PRESCAN 11 - #define WLAN_SETNONE_GETNONE (WLANIOCTL + 8) -#define WLANDEAUTH 1 -#define WLANRADIOON 2 -#define WLANRADIOOFF 3 -#define WLANREMOVEADHOCAES 4 -#define WLANADHOCSTOP 5 -#define WLANCIPHERTEST 6 -#define WLANCRYPTOTEST 7 - -#define WLANWLANIDLEON 10 -#define WLANWLANIDLEOFF 11 #define WLAN_SUBCMD_BT_RESET 13 #define WLAN_SUBCMD_FWT_RESET 14 -#define WLANGETLOG (WLANIOCTL + 9) -#define GETLOG_BUFSIZE 300 - -#define WLANSCAN_TYPE (WLANIOCTL + 11) - #define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15) #define WLANGETREGION 1 -#define WLAN_GET_LISTEN_INTERVAL 2 -#define WLAN_GET_MULTIPLE_DTIM 3 -#define WLAN_GET_TX_RATE 4 -#define WLANGETBCNAVG 5 -#define WLAN_GET_LINKMODE 6 -#define WLAN_GET_RADIOMODE 7 -#define WLAN_GET_DEBUGMODE 8 #define WLAN_SUBCMD_FWT_CLEANUP 15 #define WLAN_SUBCMD_FWT_TIME 16 #define WLAN_SUBCMD_MESH_GET_TTL 17 -#define WLANREGCFRDWR (WLANIOCTL + 18) - -#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19) -#define WLAN_SUBCMD_GETRXANTENNA 1 -#define WLAN_SUBCMD_GETTXANTENNA 2 -#define WLAN_GET_TSF 3 - -#define WLAN_SETNONE_GETWORDCHAR (WLANIOCTL + 21) -#define WLANGETADHOCAES 1 - -#define WLAN_SETONEINT_GETONEINT (WLANIOCTL + 23) -#define WLAN_BEACON_INTERVAL 1 -#define WLAN_LISTENINTRVL 4 - -#define WLAN_TXCONTROL 6 -#define WLAN_NULLPKTINTERVAL 7 - #define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24) -#define WLAN_SUBCMD_SETRXANTENNA 1 -#define WLAN_SUBCMD_SETTXANTENNA 2 -#define WLANSETAUTHALG 5 -#define WLANSET8021XAUTHALG 6 -#define WLANSETENCRYPTIONMODE 7 #define WLANSETREGION 8 -#define WLAN_SET_LISTEN_INTERVAL 9 - -#define WLAN_SET_MULTIPLE_DTIM 10 -#define WLAN_SET_ATIM_WINDOW 11 -#define WLANSETBCNAVG 13 -#define WLANSETDATAAVG 14 -#define WLAN_SET_LINKMODE 15 -#define WLAN_SET_RADIOMODE 16 -#define WLAN_SET_DEBUGMODE 17 #define WLAN_SUBCMD_MESH_SET_TTL 18 #define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25) -#define WLANSCAN_MODE 6 - -#define WLAN_GET_ADHOC_STATUS 9 - #define WLAN_SUBCMD_BT_ADD 18 #define WLAN_SUBCMD_BT_DEL 19 #define WLAN_SUBCMD_BT_LIST 20 @@ -103,27 +37,8 @@ #define WLAN_SUBCMD_FWT_LIST_ROUTE 26 #define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29) -#define WLAN_TPCCFG 1 -#define WLAN_POWERCFG 2 - -#define WLAN_AUTO_FREQ_SET 3 -#define WLAN_AUTO_FREQ_GET 4 #define WLAN_LED_GPIO_CTRL 5 -#define WLAN_SCANPROBES 6 -#define WLAN_ADAPT_RATESET 8 -#define WLAN_INACTIVITY_TIMEOUT 9 -#define WLANSNR 10 -#define WLAN_GET_RATE 11 -#define WLAN_GET_RXINFO 12 - -#define WLANCMD52RDWR (WLANIOCTL + 30) -#define WLANCMD53RDWR (WLANIOCTL + 31) -#define CMD53BUFLEN 32 -#define REG_MAC 0x19 -#define REG_BBP 0x1a -#define REG_RF 0x1b -#define REG_EEPROM 0x59 #define WLAN_LINKMODE_802_3 0 #define WLAN_LINKMODE_802_11 2 #define WLAN_RADIOMODE_NONE 0 diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index 78cf0711d1fa..ef07c36bccf7 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -249,19 +249,19 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, if (rc == PCI_SLOT_ALREADY_UP) { - dev_dbg(slot->pci_bus->self, "is already active\n"); + dev_dbg(&slot->pci_bus->self->dev, "is already active\n"); return 1; /* return 1 to user */ } if (rc == PCI_L1_ERR) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message: %s", resp.resp_sub_errno, resp.resp_l1_msg); return -EPERM; } if (rc) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "insert failed with error %d sub-error %d\n", rc, resp.resp_sub_errno); return -EIO; @@ -287,25 +287,25 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_SLOT_ALREADY_DOWN)) { - dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n"); + dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path); return 1; /* return 1 to user */ } if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "Cannot remove last 33MHz card\n"); return -EPERM; } if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message \n%s\n", resp.resp_sub_errno, resp.resp_l1_msg); return -EPERM; } if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "remove failed with error %d sub-error %d\n", rc, resp.resp_sub_errno); return -EIO; @@ -317,12 +317,12 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, if ((action == PCI_REQ_SLOT_DISABLE) && !rc) { pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus); pcibus_info->pbi_enabled_devices &= ~(1 << device_num); - dev_dbg(slot->pci_bus->self, "remove successful\n"); + dev_dbg(&slot->pci_bus->self->dev, "remove successful\n"); return 0; } if ((action == PCI_REQ_SLOT_DISABLE) && rc) { - dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc); + dev_dbg(&slot->pci_bus->self->dev,"remove failed rc = %d\n", rc); } return rc; @@ -375,7 +375,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num + 1, 0)); if (!num_funcs) { - dev_dbg(slot->pci_bus->self, "no device in slot\n"); + dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n"); mutex_unlock(&sn_hotplug_mutex); return -ENODEV; } @@ -427,7 +427,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; if (acpi_bus_get_device(phandle, &pdevice)) { - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "no parent device, assuming NULL\n"); pdevice = NULL; } @@ -479,10 +479,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) mutex_unlock(&sn_hotplug_mutex); if (rc == 0) - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "insert operation successful\n"); else - dev_dbg(slot->pci_bus->self, + dev_dbg(&slot->pci_bus->self->dev, "insert operation failed rc = %d\n", rc); return rc; @@ -659,16 +659,16 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus) if (rc) goto register_err; } - dev_dbg(pci_bus->self, "Registered bus with hotplug\n"); + dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n"); return rc; register_err: - dev_dbg(pci_bus->self, "bus failed to register with err = %d\n", + dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n", rc); alloc_err: if (rc == -ENOMEM) - dev_dbg(pci_bus->self, "Memory allocation error\n"); + dev_dbg(&pci_bus->self->dev, "Memory allocation error\n"); /* destroy THIS element */ if (bss_hotplug_slot) @@ -701,10 +701,10 @@ static int sn_pci_hotplug_init(void) rc = sn_pci_bus_valid(pci_bus); if (rc != 1) { - dev_dbg(pci_bus->self, "not a valid hotplug bus\n"); + dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n"); continue; } - dev_dbg(pci_bus->self, "valid hotplug bus\n"); + dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n"); rc = sn_hotplug_slot_register(pci_bus); if (!rc) { diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index e6740d1a0824..d9cbd586ae4b 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -549,8 +549,10 @@ static int msi_free_irqs(struct pci_dev* dev) { struct msi_desc *entry, *tmp; - list_for_each_entry(entry, &dev->msi_list, list) - BUG_ON(irq_has_action(entry->irq)); + list_for_each_entry(entry, &dev->msi_list, list) { + if (entry->irq) + BUG_ON(irq_has_action(entry->irq)); + } arch_teardown_msi_irqs(dev); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 147d86f8edbf..6ccc2e95930a 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -875,6 +875,7 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata); /* * Serverworks CSB5 IDE does not fully support native mode diff --git a/trunk/include/asm-ia64/irq.h b/trunk/include/asm-ia64/irq.h index 79479e2c6966..67221615e317 100644 --- a/trunk/include/asm-ia64/irq.h +++ b/trunk/include/asm-ia64/irq.h @@ -11,6 +11,9 @@ * 02/29/00 D.Mosberger moved most things into hw_irq.h */ +#include +#include + #define NR_IRQS 256 #define NR_IRQ_VECTORS NR_IRQS @@ -29,5 +32,8 @@ extern void disable_irq (unsigned int); extern void disable_irq_nosync (unsigned int); extern void enable_irq (unsigned int); extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); +bool is_affinity_mask_valid(cpumask_t cpumask); + +#define is_affinity_mask_valid is_affinity_mask_valid #endif /* _ASM_IA64_IRQ_H */ diff --git a/trunk/include/asm-ia64/kprobes.h b/trunk/include/asm-ia64/kprobes.h index 828ae00e47c1..2abc98b336f3 100644 --- a/trunk/include/asm-ia64/kprobes.h +++ b/trunk/include/asm-ia64/kprobes.h @@ -71,13 +71,15 @@ struct prev_kprobe { #define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f) /* per-cpu kprobe control block */ +#define ARCH_PREV_KPROBE_SZ 2 struct kprobe_ctlblk { unsigned long kprobe_status; struct pt_regs jprobe_saved_regs; unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE]; unsigned long *bsp; unsigned long cfm; - struct prev_kprobe prev_kprobe; + atomic_t prev_kprobe_index; + struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ]; }; #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry diff --git a/trunk/include/asm-ia64/pgalloc.h b/trunk/include/asm-ia64/pgalloc.h index 560c287b1233..67552cad5173 100644 --- a/trunk/include/asm-ia64/pgalloc.h +++ b/trunk/include/asm-ia64/pgalloc.h @@ -18,71 +18,18 @@ #include #include #include +#include #include -DECLARE_PER_CPU(unsigned long *, __pgtable_quicklist); -#define pgtable_quicklist __ia64_per_cpu_var(__pgtable_quicklist) -DECLARE_PER_CPU(long, __pgtable_quicklist_size); -#define pgtable_quicklist_size __ia64_per_cpu_var(__pgtable_quicklist_size) - -static inline long pgtable_quicklist_total_size(void) -{ - long ql_size = 0; - int cpuid; - - for_each_online_cpu(cpuid) { - ql_size += per_cpu(__pgtable_quicklist_size, cpuid); - } - return ql_size; -} - -static inline void *pgtable_quicklist_alloc(void) -{ - unsigned long *ret = NULL; - - preempt_disable(); - - ret = pgtable_quicklist; - if (likely(ret != NULL)) { - pgtable_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - --pgtable_quicklist_size; - preempt_enable(); - } else { - preempt_enable(); - ret = (unsigned long *)__get_free_page(GFP_KERNEL | __GFP_ZERO); - } - - return ret; -} - -static inline void pgtable_quicklist_free(void *pgtable_entry) -{ -#ifdef CONFIG_NUMA - int nid = page_to_nid(virt_to_page(pgtable_entry)); - - if (unlikely(nid != numa_node_id())) { - free_page((unsigned long)pgtable_entry); - return; - } -#endif - - preempt_disable(); - *(unsigned long *)pgtable_entry = (unsigned long)pgtable_quicklist; - pgtable_quicklist = (unsigned long *)pgtable_entry; - ++pgtable_quicklist_size; - preempt_enable(); -} - static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - return pgtable_quicklist_alloc(); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pgd_free(pgd_t * pgd) { - pgtable_quicklist_free(pgd); + quicklist_free(0, NULL, pgd); } #ifdef CONFIG_PGTABLE_4 @@ -94,12 +41,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud) static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { - return pgtable_quicklist_alloc(); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pud_free(pud_t * pud) { - pgtable_quicklist_free(pud); + quicklist_free(0, NULL, pud); } #define __pud_free_tlb(tlb, pud) pud_free(pud) #endif /* CONFIG_PGTABLE_4 */ @@ -112,12 +59,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - return pgtable_quicklist_alloc(); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pmd_free(pmd_t * pmd) { - pgtable_quicklist_free(pmd); + quicklist_free(0, NULL, pmd); } #define __pmd_free_tlb(tlb, pmd) pmd_free(pmd) @@ -137,28 +84,31 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte) static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr) { - void *pg = pgtable_quicklist_alloc(); + void *pg = quicklist_alloc(0, GFP_KERNEL, NULL); return pg ? virt_to_page(pg) : NULL; } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) { - return pgtable_quicklist_alloc(); + return quicklist_alloc(0, GFP_KERNEL, NULL); } static inline void pte_free(struct page *pte) { - pgtable_quicklist_free(page_address(pte)); + quicklist_free_page(0, NULL, pte); } static inline void pte_free_kernel(pte_t * pte) { - pgtable_quicklist_free(pte); + quicklist_free(0, NULL, pte); } -#define __pte_free_tlb(tlb, pte) pte_free(pte) +static inline void check_pgt_cache(void) +{ + quicklist_trim(0, NULL, 25, 16); +} -extern void check_pgt_cache(void); +#define __pte_free_tlb(tlb, pte) pte_free(pte) #endif /* _ASM_IA64_PGALLOC_H */ diff --git a/trunk/include/asm-ia64/unistd.h b/trunk/include/asm-ia64/unistd.h index 861c8ec87b09..f049bc40ca7d 100644 --- a/trunk/include/asm-ia64/unistd.h +++ b/trunk/include/asm-ia64/unistd.h @@ -294,11 +294,13 @@ #define __NR_vmsplice 1302 /* 1303 reserved for move_pages */ #define __NR_getcpu 1304 +#define __NR_epoll_pwait 1305 +#define __NR_utimensat 1306 #ifdef __KERNEL__ -#define NR_syscalls 281 /* length of syscall table */ +#define NR_syscalls 283 /* length of syscall table */ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND diff --git a/trunk/include/linux/i2c-id.h b/trunk/include/linux/i2c-id.h index 0e8da684ce68..aa83d4163096 100644 --- a/trunk/include/linux/i2c-id.h +++ b/trunk/include/linux/i2c-id.h @@ -117,6 +117,7 @@ #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ #define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ #define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ +#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 7906d750aa77..27d936279574 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -140,7 +140,6 @@ enum { ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */ - ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */ ATA_DFLAG_INIT_MASK = (1 << 16) - 1, ATA_DFLAG_DETACH = (1 << 16), @@ -191,6 +190,7 @@ enum { ATA_PFLAG_LOADING = (1 << 4), /* boot/loading probe */ ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */ ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ + ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */ ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ @@ -254,10 +254,6 @@ enum { ATA_DMA_PAD_SZ = 4, ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, - /* masks for port functions */ - ATA_PORT_PRIMARY = (1 << 0), - ATA_PORT_SECONDARY = (1 << 1), - /* ering size */ ATA_ERING_SIZE = 32, @@ -268,13 +264,9 @@ enum { ATA_EH_REVALIDATE = (1 << 0), ATA_EH_SOFTRESET = (1 << 1), ATA_EH_HARDRESET = (1 << 2), - ATA_EH_SUSPEND = (1 << 3), - ATA_EH_RESUME = (1 << 4), - ATA_EH_PM_FREEZE = (1 << 5), ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, - ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND | - ATA_EH_RESUME | ATA_EH_PM_FREEZE, + ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, /* ata_eh_info->flags */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ @@ -466,7 +458,7 @@ struct ata_device { struct ata_ering ering; int spdn_cnt; unsigned int horkage; /* List of broken features */ -#ifdef CONFIG_SATA_ACPI +#ifdef CONFIG_ATA_ACPI /* ACPI objects info */ acpi_handle obj_handle; #endif @@ -693,8 +685,8 @@ extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI -extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, - unsigned int n_ports); +extern int ata_pci_init_one (struct pci_dev *pdev, + const struct ata_port_info * const * ppi); extern void ata_pci_remove_one (struct pci_dev *pdev); #ifdef CONFIG_PM extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); @@ -736,8 +728,6 @@ extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val); extern int ata_port_online(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap); #ifdef CONFIG_PM -extern int ata_scsi_device_resume(struct scsi_device *); -extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg); extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); #endif @@ -861,11 +851,11 @@ struct pci_bits { unsigned long val; }; -extern int ata_pci_init_native_host(struct ata_host *host, - unsigned int port_mask); +extern int ata_pci_init_native_host(struct ata_host *host); +extern int ata_pci_init_bmdma(struct ata_host *host); extern int ata_pci_prepare_native_host(struct pci_dev *pdev, const struct ata_port_info * const * ppi, - int n_ports, struct ata_host **r_host); + struct ata_host **r_host); extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long); #endif /* CONFIG_PCI */ @@ -1008,11 +998,6 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) return ata_class_absent(dev->class); } -static inline unsigned int ata_dev_ready(const struct ata_device *dev) -{ - return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED); -} - /* * port helpers */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index ae849f0d4430..ccd85e4d3b8f 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -370,6 +370,7 @@ #define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385 #define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c +#define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390 #define PCI_VENDOR_ID_VLSI 0x1004 #define PCI_DEVICE_ID_VLSI_82C592 0x0005 diff --git a/trunk/include/media/saa7146.h b/trunk/include/media/saa7146.h index 796bcf151a3a..d3f4f5a38214 100644 --- a/trunk/include/media/saa7146.h +++ b/trunk/include/media/saa7146.h @@ -58,6 +58,7 @@ struct saa7146_pgtable { unsigned long offset; /* used for custom pagetables (used for example by budget dvb cards) */ struct scatterlist *slist; + int nents; }; struct saa7146_pci_extension_data { @@ -157,6 +158,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt); void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt); int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length ); char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt); +void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt); void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data); int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop); diff --git a/trunk/include/media/saa7146_vv.h b/trunk/include/media/saa7146_vv.h index 50e33b0e9349..cce20ed5cf6c 100644 --- a/trunk/include/media/saa7146_vv.h +++ b/trunk/include/media/saa7146_vv.h @@ -216,6 +216,8 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data); extern struct saa7146_use_ops saa7146_video_uops; int saa7146_start_preview(struct saa7146_fh *fh); int saa7146_stop_preview(struct saa7146_fh *fh); +int saa7146_video_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); /* from saa7146_vbi.c */ extern struct saa7146_use_ops saa7146_vbi_uops; diff --git a/trunk/include/sound/ak4114.h b/trunk/include/sound/ak4114.h index c149d3b2558b..d647dae912b9 100644 --- a/trunk/include/sound/ak4114.h +++ b/trunk/include/sound/ak4114.h @@ -73,7 +73,7 @@ /* AK4114_REQ_FORMAT bits */ #define AK4114_MONO (1<<7) /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */ -#define AK4114_DIF2 (1<<5) /* Audio Data Control */ +#define AK4114_DIF2 (1<<6) /* Audio Data Control */ #define AK4114_DIF1 (1<<5) /* Audio Data Control */ #define AK4114_DIF0 (1<<4) /* Audio Data Control */ #define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */ @@ -158,7 +158,7 @@ #define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */ #define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */ -#define AK4114_CONTROLS 14 +#define AK4114_CONTROLS 15 typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data); typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr); diff --git a/trunk/include/sound/mpu401.h b/trunk/include/sound/mpu401.h index 8c88267e9bea..d5c1396c4c9e 100644 --- a/trunk/include/sound/mpu401.h +++ b/trunk/include/sound/mpu401.h @@ -50,6 +50,7 @@ #define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ #define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ #define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ +#define MPU401_INFO_UART_ONLY (1 << 5) /* No ENTER_UART cmd needed */ #define MPU401_MODE_BIT_INPUT 0 #define MPU401_MODE_BIT_OUTPUT 1 diff --git a/trunk/include/sound/pcm.h b/trunk/include/sound/pcm.h index deff5a92efa6..73334e0f823f 100644 --- a/trunk/include/sound/pcm.h +++ b/trunk/include/sound/pcm.h @@ -603,11 +603,8 @@ do { \ read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \ } while (0) -#define snd_pcm_group_for_each(pos, substream) \ - list_for_each(pos, &substream->group->substreams) - -#define snd_pcm_group_substream_entry(pos) \ - list_entry(pos, struct snd_pcm_substream, link_list) +#define snd_pcm_group_for_each_entry(s, substream) \ + list_for_each_entry(s, &substream->group->substreams, link_list) static inline int snd_pcm_running(struct snd_pcm_substream *substream) { diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index 42a18cc95f38..e820f0e7bdd3 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.14rc3" -#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)" +#define CONFIG_SND_VERSION "1.0.14rc4" +#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)" diff --git a/trunk/kernel/irq/proc.c b/trunk/kernel/irq/proc.c index ddde0ef9ccdc..b4f1674fca79 100644 --- a/trunk/kernel/irq/proc.c +++ b/trunk/kernel/irq/proc.c @@ -27,6 +27,10 @@ static int irq_affinity_read_proc(char *page, char **start, off_t off, return len; } +#ifndef is_affinity_mask_valid +#define is_affinity_mask_valid(val) 1 +#endif + int no_irq_affinity; static int irq_affinity_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) @@ -42,6 +46,9 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, if (err) return err; + if (!is_affinity_mask_valid(new_value)) + return -EINVAL; + /* * Do not allow disabling IRQs completely - it's a too easy * way to make the system unusable accidentally :-) At least diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c index e91f9f66f395..ded516717940 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter, onyx->i2c.driver = &onyx_driver; onyx->i2c.adapter = adapter; onyx->i2c.addr = addr & 0x7f; - strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1); + strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE); if (i2c_attach_client(&onyx->i2c)) { printk(KERN_ERR PFX "failed to attach to i2c\n"); @@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter, goto fail; } - strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1); + strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); onyx->codec.owner = THIS_MODULE; onyx->codec.init = onyx_init_codec; onyx->codec.exit = onyx_exit_codec; diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c index 041fe52cbf29..2f771f57c76f 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c @@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter, tas->i2c.addr = addr; /* seems that half is a saner default */ tas->drc_range = TAS3004_DRC_MAX / 2; - strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1); + strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE); if (i2c_attach_client(&tas->i2c)) { printk(KERN_ERR PFX "failed to attach to i2c\n"); goto fail; } - strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1); + strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); tas->codec.owner = THIS_MODULE; tas->codec.init = tas_init_codec; tas->codec.exit = tas_exit_codec; diff --git a/trunk/sound/aoa/soundbus/core.c b/trunk/sound/aoa/soundbus/core.c index 8b2e9b905cda..64d163914335 100644 --- a/trunk/sound/aoa/soundbus/core.c +++ b/trunk/sound/aoa/soundbus/core.c @@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev) #endif /* CONFIG_PM */ -extern struct device_attribute soundbus_dev_attrs[]; - static struct bus_type soundbus_bus_type = { .name = "aoa-soundbus", .probe = soundbus_probe, diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c index 0fccdbf51663..efb9441b3acf 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c @@ -23,9 +23,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Johannes Berg "); MODULE_DESCRIPTION("Apple Soundbus: I2S support"); -/* for auto-loading, declare that we handle this weird - * string that macio puts into the relevant device */ -MODULE_ALIAS("of:Ni2sTi2sC"); static int force; module_param(force, int, 0444); @@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = { { } }; +MODULE_DEVICE_TABLE(of, i2sbus_match); + static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, struct dbdma_command_mem *r, int numcmds) diff --git a/trunk/sound/aoa/soundbus/soundbus.h b/trunk/sound/aoa/soundbus/soundbus.h index 5c27297835d7..622cd37a0118 100644 --- a/trunk/sound/aoa/soundbus/soundbus.h +++ b/trunk/sound/aoa/soundbus/soundbus.h @@ -199,4 +199,6 @@ struct soundbus_driver { extern int soundbus_register_driver(struct soundbus_driver *drv); extern void soundbus_unregister_driver(struct soundbus_driver *drv); +extern struct device_attribute soundbus_dev_attrs[]; + #endif /* __SOUNDBUS_H */ diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 905234817c89..a96733a5beb8 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops, struct snd_pcm_substream *substream, int state, int do_lock) { - struct list_head *pos; struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (do_lock && s != substream) - spin_lock(&s->self_group.lock); + spin_lock_nested(&s->self_group.lock, + SINGLE_DEPTH_NESTING); res = ops->pre_action(s, state); if (res < 0) goto _unlock; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { res = ops->do_action(s, state); if (res < 0) { if (ops->undo_action) { - snd_pcm_group_for_each(pos, substream) { - s1 = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s1, substream) { if (s1 == s) /* failed stream */ break; ops->undo_action(s1, state); @@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops, goto _unlock; } } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { ops->post_action(s, state); } _unlock: if (do_lock) { /* unlock streams */ - snd_pcm_group_for_each(pos, substream) { - s1 = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s1, substream) { if (s1 != substream) spin_unlock(&s1->self_group.lock); if (s1 == s) /* end */ @@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) { struct snd_card *card; struct snd_pcm_runtime *runtime; - struct list_head *pos; + struct snd_pcm_substream *s; int result = 0; int i, num_drecs; struct drain_rec *drec, drec_tmp, *d; @@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) /* count only playback streams */ num_drecs = 0; - snd_pcm_group_for_each(pos, substream) { - struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { d = &drec[num_drecs++]; @@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream) static int snd_pcm_unlink(struct snd_pcm_substream *substream) { - struct list_head *pos; + struct snd_pcm_substream *s; int res = 0; down_write(&snd_pcm_link_rwsem); @@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream) list_del(&substream->link_list); substream->group->count--; if (substream->group->count == 1) { /* detach the last stream, too */ - snd_pcm_group_for_each(pos, substream) { - relink_to_local(snd_pcm_group_substream_entry(pos)); + snd_pcm_group_for_each_entry(s, substream) { + relink_to_local(s); break; } kfree(substream->group); diff --git a/trunk/sound/core/rtctimer.c b/trunk/sound/core/rtctimer.c index 9f7b32e1ccde..7cd5e8f5d4ce 100644 --- a/trunk/sound/core/rtctimer.c +++ b/trunk/sound/core/rtctimer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -129,7 +130,7 @@ static int __init rtctimer_init(void) struct snd_timer *timer; if (rtctimer_freq < 2 || rtctimer_freq > 8192 || - (rtctimer_freq & (rtctimer_freq - 1)) != 0) { + !is_power_of_2(rtctimer_freq)) { snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq); return -EINVAL; diff --git a/trunk/sound/drivers/mpu401/mpu401.c b/trunk/sound/drivers/mpu401/mpu401.c index 2de181ad0b05..1d563e515c17 100644 --- a/trunk/sound/drivers/mpu401/mpu401.c +++ b/trunk/sound/drivers/mpu401/mpu401.c @@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ +static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for MPU-401 device."); @@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for MPU-401 device."); module_param_array(irq, int, NULL, 0444); MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); +module_param_array(uart_enter, bool, NULL, 0444); +MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open."); static struct platform_device *platform_devices[SNDRV_CARDS]; static int pnp_registered; @@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) strcat(card->longname, "polled"); } - if ((err = snd_mpu401_uart_new(card, 0, - MPU401_HW_MPU401, - port[dev], 0, - irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) { + err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], + uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY, + irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, + NULL); + if (err < 0) { printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); goto _err; } diff --git a/trunk/sound/drivers/mpu401/mpu401_uart.c b/trunk/sound/drivers/mpu401/mpu401_uart.c index 3daa9fa56c0b..85aedc348e2d 100644 --- a/trunk/sound/drivers/mpu401/mpu401_uart.c +++ b/trunk/sound/drivers/mpu401/mpu401_uart.c @@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, return 0; } +static int snd_mpu401_do_reset(struct snd_mpu401 *mpu) +{ + if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) + return -EIO; + if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) && + snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + return -EIO; + return 0; +} + /* * input/output open/close - protected by open_mutex in rawmidi.c */ @@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + if (snd_mpu401_do_reset(mpu) < 0) goto error_out; } mpu->substream_input = substream; @@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + if (snd_mpu401_do_reset(mpu) < 0) goto error_out; } mpu->substream_output = substream; diff --git a/trunk/sound/drivers/mts64.c b/trunk/sound/drivers/mts64.c index 6c9f4c9bfeb6..ebb1bdac7237 100644 --- a/trunk/sound/drivers/mts64.c +++ b/trunk/sound/drivers/mts64.c @@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p) struct platform_device *device; device = platform_device_alloc(PLATFORM_DRIVER, device_count); - if (!device) + if (!device) return; /* Temporary assignment to forward the parport */ platform_set_drvdata(device, p); - if (platform_device_register(device) < 0) { + if (platform_device_add(device) < 0) { platform_device_put(device); return; } diff --git a/trunk/sound/drivers/portman2x4.c b/trunk/sound/drivers/portman2x4.c index b2d0ba4bd184..497cafb57d9b 100644 --- a/trunk/sound/drivers/portman2x4.c +++ b/trunk/sound/drivers/portman2x4.c @@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p) struct platform_device *device; device = platform_device_alloc(PLATFORM_DRIVER, device_count); - if (!device) + if (!device) return; /* Temporary assignment to forward the parport */ platform_set_drvdata(device, p); - if (platform_device_register(device) < 0) { + if (platform_device_add(device) < 0) { platform_device_put(device); return; } diff --git a/trunk/sound/drivers/vx/vx_hwdep.c b/trunk/sound/drivers/vx/vx_hwdep.c index e1920af4501d..9a8154c9416e 100644 --- a/trunk/sound/drivers/vx/vx_hwdep.c +++ b/trunk/sound/drivers/vx/vx_hwdep.c @@ -30,6 +30,20 @@ #ifdef SND_VX_FW_LOADER +MODULE_FIRMWARE("vx/bx_1_vxp.b56"); +MODULE_FIRMWARE("vx/bx_1_vp4.b56"); +MODULE_FIRMWARE("vx/x1_1_vx2.xlx"); +MODULE_FIRMWARE("vx/x1_2_v22.xlx"); +MODULE_FIRMWARE("vx/x1_1_vxp.xlx"); +MODULE_FIRMWARE("vx/x1_1_vp4.xlx"); +MODULE_FIRMWARE("vx/bd56002.boot"); +MODULE_FIRMWARE("vx/bd563v2.boot"); +MODULE_FIRMWARE("vx/bd563s3.boot"); +MODULE_FIRMWARE("vx/l_1_vx2.d56"); +MODULE_FIRMWARE("vx/l_1_v22.d56"); +MODULE_FIRMWARE("vx/l_1_vxp.d56"); +MODULE_FIRMWARE("vx/l_1_vp4.d56"); + int snd_vx_setup_firmware(struct vx_core *chip) { static char *fw_files[VX_TYPE_NUMS][4] = { diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index adbfd5884d06..1efb973137a6 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -36,6 +36,7 @@ MODULE_LICENSE("GPL"); #define AK4114_ADDR 0x00 /* fixed address */ static void ak4114_stats(struct work_struct *work); +static void ak4114_init_regs(struct ak4114 *chip); static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) { @@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card, for (reg = 0; reg < 5; reg++) chip->txcsb[reg] = txcsb[reg]; - snd_ak4114_reinit(chip); + ak4114_init_regs(chip); chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); chip->rcs1 = reg_read(chip, AK4114_REG_RCS1); @@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); } -void snd_ak4114_reinit(struct ak4114 *chip) +static void ak4114_init_regs(struct ak4114 *chip) { unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg; - chip->init = 1; - mb(); - flush_scheduled_work(); /* bring the chip to reset state and powerdown state */ reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); udelay(200); @@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip) reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]); /* release powerdown, everything is initialized now */ reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); +} + +void snd_ak4114_reinit(struct ak4114 *chip) +{ + chip->init = 1; + mb(); + flush_scheduled_work(); + ak4114_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; - schedule_delayed_work(&chip->work, HZ / 10); + if (chip->kctls[0]) + schedule_delayed_work(&chip->work, HZ / 10); } static unsigned int external_rate(unsigned char rcs1) @@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_in_bit_info, .get = snd_ak4114_in_bit_get, - .private_value = (6<<8) | AK4114_REG_RCS1, + .private_value = (6<<8) | AK4114_REG_RCS0, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_in_bit_info, .get = snd_ak4114_in_bit_get, - .private_value = (3<<8) | AK4114_REG_RCS1, + .private_value = (3<<8) | AK4114_REG_RCS0, +}, +{ + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 PPL Lock Status", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_ak4114_in_bit_info, + .get = snd_ak4114_in_bit_get, + .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0, } }; @@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114, kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114); if (kctl == NULL) return -ENOMEM; - if (!strstr(kctl->id.name, "Playback")) { + if (strstr(kctl->id.name, "Playback")) { if (ply_substream == NULL) { snd_ctl_free_one(kctl); ak4114->kctls[idx] = NULL; @@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114, return err; ak4114->kctls[idx] = kctl; } + /* trigger workq */ + schedule_delayed_work(&ak4114->work, HZ / 10); return 0; } +/* notify kcontrols if any parameters are changed */ +static void ak4114_notify(struct ak4114 *ak4114, + unsigned char rcs0, unsigned char rcs1, + unsigned char c0, unsigned char c1) +{ + if (!ak4114->kctls[0]) + return; + + if (rcs0 & AK4114_PAR) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[0]->id); + if (rcs0 & AK4114_V) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[1]->id); + if (rcs1 & AK4114_CCRC) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[2]->id); + if (rcs1 & AK4114_QCRC) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[3]->id); + + /* rate change */ + if (c1 & 0xf0) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[4]->id); + + if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[9]->id); + if (c0 & AK4114_QINT) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[10]->id); + + if (c0 & AK4114_AUDION) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[11]->id); + if (c0 & AK4114_AUTO) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[12]->id); + if (c0 & AK4114_DTSCD) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[13]->id); + if (c0 & AK4114_UNLCK) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[14]->id); +} + int snd_ak4114_external_rate(struct ak4114 *ak4114) { unsigned char rcs1; @@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) ak4114->rcs1 = rcs1; spin_unlock_irqrestore(&ak4114->lock, _flags); - if (rcs0 & AK4114_PAR) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id); - if (rcs0 & AK4114_V) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id); - if (rcs1 & AK4114_CCRC) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id); - if (rcs1 & AK4114_QCRC) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id); - - /* rate change */ - if (c1 & 0xf0) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id); - - if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id); - if (c0 & AK4114_QINT) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id); - - if (c0 & AK4114_AUDION) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id); - if (c0 & AK4114_AUTO) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id); - if (c0 & AK4114_DTSCD) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id); - + ak4114_notify(ak4114, rcs0, rcs1, c0, c1); if (ak4114->change_callback && (c0 | c1) != 0) ak4114->change_callback(ak4114, c0, c1); @@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work) { struct ak4114 *chip = container_of(work, struct ak4114, work.work); - if (chip->init) - return; - snd_ak4114_check_rate_and_errors(chip, 0); + if (!chip->init) + snd_ak4114_check_rate_and_errors(chip, 0); + schedule_delayed_work(&chip->work, HZ / 10); } diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index 4e3a9729f569..cf3803cd579c 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -358,12 +358,21 @@ config SND_SBAWE config SND_SB16_CSP bool "Sound Blaster 16/AWE CSP support" depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) - select FW_LOADER + select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and decompression algorithms. +config SND_SB16_CSP_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for SB16 CSP" + depends on SND_SB16_CSP + default y + help + Say Y here to include the static firmware built in the kernel + for the SB16 CSP controller. If you choose N here, you need + to install the firmware files from the alsa-firmware package. + config SND_SGALAXY tristate "Aztech Sound Galaxy" depends on SND @@ -391,7 +400,7 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND - select FW_LOADER + select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -402,4 +411,13 @@ config SND_WAVEFRONT To compile this driver as a module, choose M here: the module will be called snd-wavefront. +config SND_WAVEFRONT_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Wavefront" + depends on SND_WAVEFRONT + default y + help + Say Y here to include the static firmware built in the kernel + for the Wavefront driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + endmenu diff --git a/trunk/sound/isa/ad1816a/ad1816a.c b/trunk/sound/isa/ad1816a/ad1816a.c index 59034507175b..fc88a31da6f5 100644 --- a/trunk/sound/isa/ad1816a/ad1816a.c +++ b/trunk/sound/isa/ad1816a/ad1816a.c @@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar } acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL); if (acard->devmpu == NULL) { - kfree(cfg); - return -EBUSY; + mpu_port[dev] = -1; + snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n"); } pdev = acard->dev; @@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar dma2[dev] = pnp_dma(pdev, 1); irq[dev] = pnp_irq(pdev, 0); + if (acard->devmpu == NULL) { + kfree(cfg); + return 0; + } pdev = acard->devmpu; pnp_init_resource_table(cfg); diff --git a/trunk/sound/isa/ad1848/ad1848.c b/trunk/sound/isa/ad1848/ad1848.c index 74e501dea8b1..d09a7fa86545 100644 --- a/trunk/sound/isa/ad1848/ad1848.c +++ b/trunk/sound/isa/ad1848/ad1848.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,8 +32,11 @@ #include #include +#define CRD_NAME "Generic AD1848/AD1847/CS4248" +#define DEV_NAME "ad1848" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Tugrul Galatali , Jaroslav Kysela "); -MODULE_DESCRIPTION("AD1848/AD1847/CS4248"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848}," "{Analog Devices,AD1847}," @@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for AD1848 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for AD1848 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable AD1848 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for AD1848 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(thinkpad, bool, NULL, 0444); MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_ad1848_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + if (irq[n] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); + return 0; + } + if (dma1[n] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); + return 0; + } + return 1; +} -static int __devinit snd_ad1848_probe(struct platform_device *pdev) +static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; struct snd_card *card; struct snd_ad1848 *chip; struct snd_pcm *pcm; - int err; + int error; - if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "ad1848: specify port\n"); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) return -EINVAL; - } - if (irq[dev] == SNDRV_AUTO_IRQ) { - snd_printk(KERN_ERR "ad1848: specify irq\n"); - return -EINVAL; - } - if (dma1[dev] == SNDRV_AUTO_DMA) { - snd_printk(KERN_ERR "ad1848: specify dma1\n"); - return -EINVAL; - } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + error = snd_ad1848_create(card, port[n], irq[n], dma1[n], + thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip); + if (error < 0) + goto out; - if ((err = snd_ad1848_create(card, port[dev], - irq[dev], - dma1[dev], - thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, - &chip)) < 0) - goto _err; card->private_data = chip; - if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_ad1848_pcm(chip, 0, &pcm); + if (error < 0) + goto out; - if ((err = snd_ad1848_mixer(chip)) < 0) - goto _err; + error = snd_ad1848_mixer(chip); + if (error < 0) + goto out; strcpy(card->driver, "AD1848"); strcpy(card->shortname, pcm->name); sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - pcm->name, chip->port, irq[dev], dma1[dev]); - - if (thinkpad[dev]) + pcm->name, chip->port, irq[n], dma1[n]); + if (thinkpad[n]) strcat(card->longname, " [Thinkpad]"); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_ad1848_remove(struct platform_device *devptr) +static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) +static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_ad1848 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); @@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int snd_ad1848_resume(struct platform_device *pdev) +static int snd_ad1848_resume(struct device *dev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_ad1848 *chip = card->private_data; chip->resume(chip); @@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev) } #endif -#define SND_AD1848_DRIVER "snd_ad1848" - -static struct platform_driver snd_ad1848_driver = { +static struct isa_driver snd_ad1848_driver = { + .match = snd_ad1848_match, .probe = snd_ad1848_probe, .remove = __devexit_p(snd_ad1848_remove), #ifdef CONFIG_PM @@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = { .resume = snd_ad1848_resume, #endif .driver = { - .name = SND_AD1848_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_ad1848_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_ad1848_driver); -} - static int __init alsa_card_ad1848_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_ad1848_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_AD1848_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "AD1848 soundcard not found or device busy\n"); -#endif - snd_ad1848_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS); } static void __exit alsa_card_ad1848_exit(void) { - snd_ad1848_unregister_all(); + isa_unregister_driver(&snd_ad1848_driver); } -module_init(alsa_card_ad1848_init) -module_exit(alsa_card_ad1848_exit) +module_init(alsa_card_ad1848_init); +module_exit(alsa_card_ad1848_exit); diff --git a/trunk/sound/isa/adlib.c b/trunk/sound/isa/adlib.c index 1124344ed948..d68720724c91 100644 --- a/trunk/sound/isa/adlib.c +++ b/trunk/sound/isa/adlib.c @@ -5,13 +5,13 @@ #include #include #include -#include +#include #include #include #include #define CRD_NAME "AdLib FM" -#define DRV_NAME "snd_adlib" +#define DEV_NAME "adlib" MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Rene Herman"); @@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_adlib_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + return 1; +} static void snd_adlib_free(struct snd_card *card) { release_and_free_resource(card->private_data); } -static int __devinit snd_adlib_probe(struct platform_device *device) +static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) { struct snd_card *card; struct snd_opl3 *opl3; + int error; - int error, i = device->id; - - if (port[i] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR DRV_NAME ": please specify port\n"); - error = -EINVAL; - goto out0; - } - - card = snd_card_new(index[i], id[i], THIS_MODULE, 0); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); if (!card) { - snd_printk(KERN_ERR DRV_NAME ": could not create card\n"); - error = -EINVAL; - goto out0; + snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id); + return -EINVAL; } - card->private_data = request_region(port[i], 4, CRD_NAME); + card->private_data = request_region(port[n], 4, CRD_NAME); if (!card->private_data) { - snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n"); + snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id); error = -EBUSY; - goto out1; + goto out; } card->private_free = snd_adlib_free; - error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3); + strcpy(card->driver, DEV_NAME); + strcpy(card->shortname, CRD_NAME); + sprintf(card->longname, CRD_NAME " at %#lx", port[n]); + + error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id); + goto out; } error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create FM\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id); + goto out; } - strcpy(card->driver, DRV_NAME); - strcpy(card->shortname, CRD_NAME); - sprintf(card->longname, CRD_NAME " at %#lx", port[i]); - - snd_card_set_dev(card, &device->dev); + snd_card_set_dev(card, dev); error = snd_card_register(card); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register card\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id); + goto out; } - platform_set_drvdata(device, card); + dev_set_drvdata(dev, card); return 0; -out1: snd_card_free(card); -out0: return error; +out: snd_card_free(card); + return error; } -static int __devexit snd_adlib_remove(struct platform_device *device) +static int __devexit snd_adlib_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(device)); - platform_set_drvdata(device, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -static struct platform_driver snd_adlib_driver = { +static struct isa_driver snd_adlib_driver = { + .match = snd_adlib_match, .probe = snd_adlib_probe, .remove = __devexit_p(snd_adlib_remove), .driver = { - .name = DRV_NAME + .name = DEV_NAME } }; static int __init alsa_card_adlib_init(void) { - int i, cards; - - if (platform_driver_register(&snd_adlib_driver) < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register driver\n"); - return -ENODEV; - } - - for (cards = 0, i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - - if (!enable[i]) - continue; - - device = platform_device_register_simple(DRV_NAME, i, NULL, 0); - if (IS_ERR(device)) - continue; - - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - - devices[i] = device; - cards++; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n"); -#endif - platform_driver_unregister(&snd_adlib_driver); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS); } static void __exit alsa_card_adlib_exit(void) { - int i; - - for (i = 0; i < SNDRV_CARDS; i++) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_adlib_driver); + isa_unregister_driver(&snd_adlib_driver); } module_init(alsa_card_adlib_init); diff --git a/trunk/sound/isa/cmi8330.c b/trunk/sound/isa/cmi8330.c index c09a8009d2fa..214d65d94c45 100644 --- a/trunk/sound/isa/cmi8330.c +++ b/trunk/sound/isa/cmi8330.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); module_param_array(wssdma, int, NULL, 0444); MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; #endif @@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_cmi8330_isa_match(struct device *pdev, + unsigned int dev) { - struct snd_card *card; - int err; - int dev = pdev->id; - + if (!enable[dev] || is_isapnp_selected(dev)) + return 0; if (wssport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify wssport\n"); - return -EINVAL; + return 0; } if (sbport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify sbport\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_cmi8330_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_cmi8330_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_cmi8330_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_cmi8330_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_cmi8330_suspend(platform_get_drvdata(dev)); + return snd_cmi8330_suspend(dev_get_drvdata(dev)); } -static int snd_cmi8330_nonpnp_resume(struct platform_device *dev) +static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n) { - return snd_cmi8330_resume(platform_get_drvdata(dev)); + return snd_cmi8330_resume(dev_get_drvdata(dev)); } #endif -#define CMI8330_DRIVER "snd_cmi8330" +#define DEV_NAME "cmi8330" -static struct platform_driver snd_cmi8330_driver = { - .probe = snd_cmi8330_nonpnp_probe, - .remove = __devexit_p(snd_cmi8330_nonpnp_remove), +static struct isa_driver snd_cmi8330_driver = { + .match = snd_cmi8330_isa_match, + .probe = snd_cmi8330_isa_probe, + .remove = __devexit_p(snd_cmi8330_isa_remove), #ifdef CONFIG_PM - .suspend = snd_cmi8330_nonpnp_suspend, - .resume = snd_cmi8330_nonpnp_resume, + .suspend = snd_cmi8330_isa_suspend, + .resume = snd_cmi8330_isa_resume, #endif .driver = { - .name = CMI8330_DRIVER + .name = DEV_NAME }, }; #ifdef CONFIG_PNP -static unsigned int __devinitdata cmi8330_pnp_devices; - static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - cmi8330_pnp_devices++; return 0; } @@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_cmi8330_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&cmi8330_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_cmi8330_driver); -} - static int __init alsa_card_cmi8330_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0) + err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(CMI8330_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_card_driver(&cmi8330_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += cmi8330_pnp_devices; - } #endif - - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "CMI8330 not found or device busy\n"); -#endif - snd_cmi8330_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_cmi8330_exit(void) { - snd_cmi8330_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&cmi8330_pnpc_driver); +#endif + isa_unregister_driver(&snd_cmi8330_driver); } module_init(alsa_card_cmi8330_init) diff --git a/trunk/sound/isa/cs423x/cs4231.c b/trunk/sound/isa/cs423x/cs4231.c index 696a5c86bcfa..ac4041134150 100644 --- a/trunk/sound/isa/cs423x/cs4231.c +++ b/trunk/sound/isa/cs423x/cs4231.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,8 +32,11 @@ #include #include +#define CRD_NAME "Generic CS4231" +#define DEV_NAME "cs4231" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Generic CS4231"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}"); @@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for CS4231 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for CS4231 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable CS4231 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for CS4231 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(dma2, int, NULL, 0444); -MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); +MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_cs4231_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + if (irq[n] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); + return 0; + } + if (dma1[n] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); + return 0; + } + return 1; +} -static int __init snd_cs4231_probe(struct platform_device *pdev) +static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; struct snd_card *card; - struct snd_pcm *pcm; struct snd_cs4231 *chip; - int err; + struct snd_pcm *pcm; + int error; - if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify port\n"); - return -EINVAL; - } - if (irq[dev] == SNDRV_AUTO_IRQ) { - snd_printk(KERN_ERR "specify irq\n"); - return -EINVAL; - } - if (dma1[dev] == SNDRV_AUTO_DMA) { - snd_printk(KERN_ERR "specify dma1\n"); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) return -EINVAL; - } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if ((err = snd_cs4231_create(card, port[dev], -1, - irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, - 0, &chip)) < 0) - goto _err; + + error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n], + CS4231_HW_DETECT, 0, &chip); + if (error < 0) + goto out; + card->private_data = chip; - if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_cs4231_pcm(chip, 0, &pcm); + if (error < 0) + goto out; strcpy(card->driver, "CS4231"); strcpy(card->shortname, pcm->name); + sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - pcm->name, chip->port, irq[dev], dma1[dev]); - if (dma2[dev] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); - - if ((err = snd_cs4231_mixer(chip)) < 0) - goto _err; - if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) - goto _err; - - if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { - if (mpu_irq[dev] == SNDRV_AUTO_IRQ) - mpu_irq[dev] = -1; + pcm->name, chip->port, irq[n], dma1[n]); + if (dma2[n] >= 0) + sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); + + error = snd_cs4231_mixer(chip); + if (error < 0) + goto out; + + error = snd_cs4231_timer(chip, 0, NULL); + if (error < 0) + goto out; + + if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) { + if (mpu_irq[n] == SNDRV_AUTO_IRQ) + mpu_irq[n] = -1; if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, - mpu_port[dev], 0, - mpu_irq[dev], - mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, + mpu_port[n], 0, mpu_irq[n], + mpu_irq[n] >= 0 ? IRQF_DISABLED : 0, NULL) < 0) - printk(KERN_WARNING "cs4231: MPU401 not detected\n"); + printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id); } - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_cs4231_remove(struct platform_device *devptr) +static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state) { - struct snd_card *card; - struct snd_cs4231 *chip; - card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); + struct snd_cs4231 *chip = card->private_data; + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip = card->private_data; chip->suspend(chip); return 0; } -static int snd_cs4231_resume(struct platform_device *dev) +static int snd_cs4231_resume(struct device *dev, unsigned int n) { - struct snd_card *card; - struct snd_cs4231 *chip; - card = platform_get_drvdata(dev); - chip = card->private_data; + struct snd_card *card = dev_get_drvdata(dev); + struct snd_cs4231 *chip = card->private_data; + chip->resume(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } #endif -#define SND_CS4231_DRIVER "snd_cs4231" - -static struct platform_driver snd_cs4231_driver = { +static struct isa_driver snd_cs4231_driver = { + .match = snd_cs4231_match, .probe = snd_cs4231_probe, .remove = __devexit_p(snd_cs4231_remove), #ifdef CONFIG_PM @@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = { .resume = snd_cs4231_resume, #endif .driver = { - .name = SND_CS4231_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_cs4231_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_cs4231_driver); -} - static int __init alsa_card_cs4231_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_cs4231_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_CS4231_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); -#endif - snd_cs4231_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS); } static void __exit alsa_card_cs4231_exit(void) { - snd_cs4231_unregister_all(); + isa_unregister_driver(&snd_cs4231_driver); } -module_init(alsa_card_cs4231_init) -module_exit(alsa_card_cs4231_exit) +module_init(alsa_card_cs4231_init); +module_exit(alsa_card_cs4231_exit); diff --git a/trunk/sound/isa/cs423x/cs4231_lib.c b/trunk/sound/isa/cs423x/cs4231_lib.c index 75c7c5f01989..914d77b61b0c 100644 --- a/trunk/sound/isa/cs423x/cs4231_lib.c +++ b/trunk/sound/isa/cs423x/cs4231_lib.c @@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); int result = 0; unsigned int what; - struct list_head *pos; struct snd_pcm_substream *s; int do_start; @@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, } what = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == chip->playback_substream) { what |= CS4231_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); diff --git a/trunk/sound/isa/cs423x/cs4236.c b/trunk/sound/isa/cs423x/cs4236.c index 07ffd5c22e81..87f1392a2fa7 100644 --- a/trunk/sound/isa/cs423x/cs4236.c +++ b/trunk/sound/isa/cs423x/cs4236.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," #ifdef CS4232 #define IDENT "CS4232" -#define CS423X_DRIVER "snd_cs4232" +#define DEV_NAME "cs4232" #else #define IDENT "CS4236+" -#define CS423X_DRIVER "snd_cs4236" +#define DEV_NAME "cs4236" #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ @@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver."); module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnpc_registered; #ifdef CS4232 static int pnp_registered; #endif #endif /* CONFIG_PNP */ -static unsigned int snd_cs423x_devices; struct snd_card_cs4236 { struct snd_cs4231 *chip; @@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_cs423x_isa_match(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; - struct snd_card *card; - int err; + if (!enable[dev] || is_isapnp_selected(dev)) + return 0; if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify port\n"); - return -EINVAL; + snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id); + return 0; } if (cport[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify cport\n"); - return -EINVAL; + snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id); + return 0; + } + if (irq[dev] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); + return 0; } + if (dma1[dev] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id); + return 0; + } + return 1; +} + +static int __devinit snd_cs423x_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_cs423x_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_cs423x_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_cs423x_isa_remove(struct device *pdev, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } @@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card) return 0; } -static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_cs423x_suspend(platform_get_drvdata(dev)); + return snd_cs423x_suspend(dev_get_drvdata(dev)); } -static int snd_cs423x_nonpnp_resume(struct platform_device *dev) +static int snd_cs423x_isa_resume(struct device *dev, unsigned int n) { - return snd_cs423x_resume(platform_get_drvdata(dev)); + return snd_cs423x_resume(dev_get_drvdata(dev)); } #endif -static struct platform_driver cs423x_nonpnp_driver = { - .probe = snd_cs423x_nonpnp_probe, - .remove = __devexit_p(snd_cs423x_nonpnp_remove), +static struct isa_driver cs423x_isa_driver = { + .match = snd_cs423x_isa_match, + .probe = snd_cs423x_isa_probe, + .remove = __devexit_p(snd_cs423x_isa_remove), #ifdef CONFIG_PM - .suspend = snd_cs423x_nonpnp_suspend, - .resume = snd_cs423x_nonpnp_resume, + .suspend = snd_cs423x_isa_suspend, + .resume = snd_cs423x_isa_resume, #endif .driver = { - .name = CS423X_DRIVER + .name = DEV_NAME }, }; @@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_cs423x_devices++; return 0; } @@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_cs423x_devices++; return 0; } @@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_cs423x_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&cs423x_pnpc_driver); -#ifdef CS4232 - if (pnp_registered) - pnp_unregister_driver(&cs4232_pnp_driver); -#endif -#endif /* CONFIG_PNP */ - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&cs423x_nonpnp_driver); -} - static int __init alsa_card_cs423x_init(void) { - int i, err; + int err; - if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) + err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(CS423X_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - snd_cs423x_devices++; - } #ifdef CONFIG_PNP #ifdef CS4232 err = pnp_register_driver(&cs4232_pnp_driver); @@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void) if (!err) pnpc_registered = 1; #endif /* CONFIG_PNP */ - - if (!snd_cs423x_devices) { -#ifdef MODULE - printk(KERN_ERR IDENT " soundcard not found or device busy\n"); -#endif - snd_cs423x_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_cs423x_exit(void) { - snd_cs423x_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&cs423x_pnpc_driver); +#ifdef CS4232 + if (pnp_registered) + pnp_unregister_driver(&cs4232_pnp_driver); +#endif +#endif /* CONFIG_PNP */ + isa_unregister_driver(&cs423x_isa_driver); } module_init(alsa_card_cs423x_init) diff --git a/trunk/sound/isa/es1688/es1688.c b/trunk/sound/isa/es1688/es1688.c index 65f97ff4eef1..edc398712e8b 100644 --- a/trunk/sound/isa/es1688/es1688.c +++ b/trunk/sound/isa/es1688/es1688.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,8 +35,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive" +#define DEV_NAME "es1688" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("ESS ESx688 AudioDrive"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102}," @@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for ESx688 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for ESx688 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable ESx688 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for ESx688 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); - -static struct platform_device *devices[SNDRV_CARDS]; +MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); -#define PFX "es1688: " +static int __devinit snd_es1688_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} -static int __devinit snd_es1688_probe(struct platform_device *pdev) +static int __devinit snd_es1688_legacy_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_es1688 **rchip) { - int dev = pdev->id; + static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas[] = {1, 3, 0, -1}; - int xirq, xdma, xmpu_irq; - struct snd_card *card; - struct snd_es1688 *chip; - struct snd_opl3 *opl3; - struct snd_pcm *pcm; - int err; - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - - xirq = irq[dev]; - if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - err = -EBUSY; - goto _err; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", + dev->bus_id); + return -EBUSY; } } - xmpu_irq = mpu_irq[dev]; - xdma = dma8[dev]; - if (xdma == SNDRV_AUTO_DMA) { - if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA\n"); - err = -EBUSY; - goto _err; + if (dma8[n] == SNDRV_AUTO_DMA) { + dma8[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma8[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA\n", + dev->bus_id); + return -EBUSY; } } - if (port[dev] != SNDRV_AUTO_PORT) { - if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], - xirq, xmpu_irq, xdma, - ES1688_HW_AUTO, &chip)) < 0) - goto _err; - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = { - 0x220, 0x240, 0x260, - }; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_es1688_create(card, possible_ports[i], - mpu_port[dev], - xirq, xmpu_irq, xdma, - ES1688_HW_AUTO, &chip); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - if (i >= ARRAY_SIZE(possible_ports)) - goto _err; - } + if (port[n] != SNDRV_AUTO_PORT) + return snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); + + return error; +} + +static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) +{ + struct snd_card *card; + struct snd_es1688 *chip; + struct snd_opl3 *opl3; + struct snd_pcm *pcm; + int error; + + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; + + error = snd_es1688_legacy_create(card, dev, n, &chip); + if (error < 0) + goto out; - if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_es1688_pcm(chip, 0, &pcm); + if (error < 0) + goto out; - if ((err = snd_es1688_mixer(chip)) < 0) - goto _err; + error = snd_es1688_mixer(chip); + if (error < 0) + goto out; strcpy(card->driver, "ES1688"); strcpy(card->shortname, pcm->name); - sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma); - - if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) { - printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port); - } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) - goto _err; + sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, + chip->port, chip->irq, chip->dma8); + + if (snd_opl3_create(card, chip->port, chip->port + 2, + OPL3_HW_OPL3, 0, &opl3) < 0) + printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", + dev->bus_id, chip->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (error < 0) + goto out; } - if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) { - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, - chip->mpu_port, 0, - xmpu_irq, - IRQF_DISABLED, - NULL)) < 0) - goto _err; + if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && + chip->mpu_port > 0) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, + chip->mpu_port, 0, + mpu_irq[n], IRQF_DISABLED, NULL); + if (error < 0) + goto out; } - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_es1688_remove(struct platform_device *devptr) +static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define ES1688_DRIVER "snd_es1688" - -static struct platform_driver snd_es1688_driver = { +static struct isa_driver snd_es1688_driver = { + .match = snd_es1688_match, .probe = snd_es1688_probe, - .remove = __devexit_p(snd_es1688_remove), - /* FIXME: suspend/resume */ + .remove = snd_es1688_remove, +#if 0 /* FIXME */ + .suspend = snd_es1688_suspend, + .resume = snd_es1688_resume, +#endif .driver = { - .name = ES1688_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_es1688_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_es1688_driver); -} - static int __init alsa_card_es1688_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_es1688_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(ES1688_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); -#endif - snd_es1688_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); } static void __exit alsa_card_es1688_exit(void) { - snd_es1688_unregister_all(); + isa_unregister_driver(&snd_es1688_driver); } -module_init(alsa_card_es1688_init) -module_exit(alsa_card_es1688_exit) +module_init(alsa_card_es1688_init); +module_exit(alsa_card_es1688_exit); diff --git a/trunk/sound/isa/es18xx.c b/trunk/sound/isa/es18xx.c index 725c115ff97d..d2a9c7df0ce5 100644 --- a/trunk/sound/isa/es18xx.c +++ b/trunk/sound/isa/es18xx.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #include #include #include @@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver."); module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered, pnpc_registered; @@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev) +{ + return enable[dev] && !is_isapnp_selected(dev); +} + +static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) { struct snd_card *card; int err; @@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d card = snd_es18xx_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_audiodrive_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; static int possible_dmas[] = {1, 0, 3, 5, -1}; @@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) { - return snd_es18xx_nonpnp_probe1(dev, pdev); + return snd_es18xx_isa_probe1(dev, pdev); } else { static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_es18xx_nonpnp_probe1(dev, pdev); + err = snd_es18xx_isa_probe1(dev, pdev); if (! err) return 0; } @@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_es18xx_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_es18xx_suspend(platform_get_drvdata(dev), state); + return snd_es18xx_suspend(dev_get_drvdata(dev), state); } -static int snd_es18xx_nonpnp_resume(struct platform_device *dev) +static int snd_es18xx_isa_resume(struct device *dev, unsigned int n) { - return snd_es18xx_resume(platform_get_drvdata(dev)); + return snd_es18xx_resume(dev_get_drvdata(dev)); } #endif -#define ES18XX_DRIVER "snd_es18xx" +#define DEV_NAME "es18xx" -static struct platform_driver snd_es18xx_nonpnp_driver = { - .probe = snd_es18xx_nonpnp_probe, - .remove = __devexit_p(snd_es18xx_nonpnp_remove), +static struct isa_driver snd_es18xx_isa_driver = { + .match = snd_es18xx_isa_match, + .probe = snd_es18xx_isa_probe, + .remove = __devexit_p(snd_es18xx_isa_remove), #ifdef CONFIG_PM - .suspend = snd_es18xx_nonpnp_suspend, - .resume = snd_es18xx_nonpnp_resume, + .suspend = snd_es18xx_isa_suspend, + .resume = snd_es18xx_isa_resume, #endif .driver = { - .name = ES18XX_DRIVER + .name = DEV_NAME }, }; #ifdef CONFIG_PNP -static unsigned int __devinitdata es18xx_pnp_devices; - static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, const struct pnp_device_id *id) { @@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - es18xx_pnp_devices++; return 0; } @@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - es18xx_pnp_devices++; return 0; } @@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_es18xx_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&es18xx_pnpc_driver); - if (pnp_registered) - pnp_unregister_driver(&es18xx_pnp_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_es18xx_nonpnp_driver); -} - static int __init alsa_card_es18xx_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(ES18XX_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_driver(&es18xx_pnp_driver); if (!err) @@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void) err = pnp_register_card_driver(&es18xx_pnpc_driver); if (!err) pnpc_registered = 1; - cards += es18xx_pnp_devices; -#endif - - if(!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); #endif - snd_es18xx_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_es18xx_exit(void) { - snd_es18xx_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&es18xx_pnpc_driver); + if (pnp_registered) + pnp_unregister_driver(&es18xx_pnp_driver); +#endif + isa_unregister_driver(&snd_es18xx_isa_driver); } module_init(alsa_card_es18xx_init) diff --git a/trunk/sound/isa/gus/gusclassic.c b/trunk/sound/isa/gus/gusclassic.c index 0395e2e0dd03..8f23f433d491 100644 --- a/trunk/sound/isa/gus/gusclassic.c +++ b/trunk/sound/isa/gus/gusclassic.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,8 +33,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Gravis UltraSound Classic" +#define DEV_NAME "gusclassic" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Gravis UltraSound Classic"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); @@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Classic driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(dma2, int, NULL, 0444); -MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver."); +MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); + +static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int __devinit snd_gusclassic_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_gus_card **rgus) +{ + static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260}; + static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; + static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", + dev->bus_id); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA1\n", + dev->bus_id); + return -EBUSY; + } + } + if (dma2[n] == SNDRV_AUTO_DMA) { + dma2[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma2[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA2\n", + dev->bus_id); + return -EBUSY; + } + } -static struct platform_device *devices[SNDRV_CARDS]; + if (port[n] != SNDRV_AUTO_PORT) + return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); -#define PFX "gusclassic: " + return error; +} -static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) +static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus) { unsigned char d; @@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) return 0; } -static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus) -{ - gus->equal_irq = 0; - gus->codec_flag = 0; - gus->max_flag = 0; - gus->joystick_dac = joystick_dac[dev]; -} - -static int __devinit snd_gusclassic_probe(struct platform_device *pdev) +static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; - static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; - int xirq, xdma1, xdma2; struct snd_card *card; - struct snd_gus_card *gus = NULL; - int err; - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if (pcm_channels[dev] < 2) - pcm_channels[dev] = 2; - - xirq = irq[dev]; - if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - err = -EBUSY; - goto _err; - } - } - xdma1 = dma1[dev]; - if (xdma1 == SNDRV_AUTO_DMA) { - if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); - err = -EBUSY; - goto _err; - } - } - xdma2 = dma2[dev]; - if (xdma2 == SNDRV_AUTO_DMA) { - if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); - err = -EBUSY; - goto _err; - } - } + struct snd_gus_card *gus; + int error; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_gus_create(card, - port[dev], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = { - 0x220, 0x230, 0x240, 0x250, 0x260, - }; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_gus_create(card, - possible_ports[i], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) - goto _err; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; - if ((err = snd_gusclassic_detect(gus)) < 0) - goto _err; + if (pcm_channels[n] < 2) + pcm_channels[n] = 2; - snd_gusclassic_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) - goto _err; + error = snd_gusclassic_create(card, dev, n, &gus); + if (error < 0) + goto out; + error = snd_gusclassic_detect(gus); + if (error < 0) + goto out; + + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) + goto out; + + error = -ENODEV; if (gus->max_flag || gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; - goto _err; + snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was " + "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port); + goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) - goto _err; + error = snd_gf1_new_mixer(gus); + if (error < 0) + goto out; - if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) - goto _err; + error = snd_gf1_pcm_new(gus, 0, 0, NULL); + if (error < 0) + goto out; if (!gus->ace_flag) { - if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) - goto _err; + error = snd_gf1_rawmidi_new(gus, 0, NULL); + if (error < 0) + goto out; } - sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1); - if (xdma2 >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", xdma2); - snd_card_set_dev(card, &pdev->dev); + sprintf(card->longname + strlen(card->longname), + " at 0x%lx, irq %d, dma %d", + gus->gf1.port, gus->gf1.irq, gus->gf1.dma1); - if ((err = snd_card_register(card)) < 0) - goto _err; + if (gus->gf1.dma2 >= 0) + sprintf(card->longname + strlen(card->longname), + "&%d", gus->gf1.dma2); - platform_set_drvdata(pdev, card); + snd_card_set_dev(card, dev); + + error = snd_card_register(card); + if (error < 0) + goto out; + + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_gusclassic_remove(struct platform_device *devptr) +static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define GUSCLASSIC_DRIVER "snd_gusclassic" - -static struct platform_driver snd_gusclassic_driver = { +static struct isa_driver snd_gusclassic_driver = { + .match = snd_gusclassic_match, .probe = snd_gusclassic_probe, .remove = __devexit_p(snd_gusclassic_remove), - /* FIXME: suspend/resume */ +#if 0 /* FIXME */ + .suspend = snd_gusclassic_suspend, + .remove = snd_gusclassic_remove, +#endif .driver = { - .name = GUSCLASSIC_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusclassic_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusclassic_driver); -} - static int __init alsa_card_gusclassic_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusclassic_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSCLASSIC_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); -#endif - snd_gusclassic_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS); } static void __exit alsa_card_gusclassic_exit(void) { - snd_gusclassic_unregister_all(); + isa_unregister_driver(&snd_gusclassic_driver); } -module_init(alsa_card_gusclassic_init) -module_exit(alsa_card_gusclassic_exit) +module_init(alsa_card_gusclassic_init); +module_exit(alsa_card_gusclassic_exit); diff --git a/trunk/sound/isa/gus/gusextreme.c b/trunk/sound/isa/gus/gusextreme.c index 4f55fc3e66c1..0aeaa6cf6cf0 100644 --- a/trunk/sound/isa/gus/gusextreme.c +++ b/trunk/sound/isa/gus/gusextreme.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -37,8 +37,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Gravis UltraSound Extreme" +#define DEV_NAME "gusextreme" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Gravis UltraSound Extreme"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); @@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Extreme driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(gf1_port, long, NULL, 0444); -MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional)."); +MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional)."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(gf1_irq, int, NULL, 0444); -MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); + +static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_es1688 **rchip) +{ + static long possible_ports[] = {0x220, 0x240, 0x260}; + static int possible_irqs[] = {5, 9, 10, 7, -1}; + static int possible_dmas[] = {1, 3, 0, -1}; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ " + "for ES1688\n", dev->bus_id); + return -EBUSY; + } + } + if (dma8[n] == SNDRV_AUTO_DMA) { + dma8[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma8[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA " + "for ES1688\n", dev->bus_id); + return -EBUSY; + } + } -static struct platform_device *devices[SNDRV_CARDS]; + if (port[n] != SNDRV_AUTO_PORT) + return snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); -#define PFX "gusextreme: " + return error; +} -static int __devinit snd_gusextreme_detect(int dev, - struct snd_card *card, - struct snd_gus_card * gus, - struct snd_es1688 *es1688) +static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_gus_card **rgus) +{ + static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1}; + static int possible_dmas[] = {5, 6, 7, 3, 1, -1}; + + if (gf1_irq[n] == SNDRV_AUTO_IRQ) { + gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (gf1_irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ " + "for GF1\n", dev->bus_id); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA " + "for GF1\n", dev->bus_id); + return -EBUSY; + } + } + return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1, + 0, channels[n], pcm_channels[n], 0, rgus); +} + +static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus, + struct snd_es1688 *es1688) { unsigned long flags; unsigned char d; @@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev, spin_lock_irqsave(&es1688->mixer_lock, flags); snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ spin_unlock_irqrestore(&es1688->mixer_lock, flags); + spin_lock_irqsave(&es1688->reg_lock, flags); - outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); spin_unlock_irqrestore(&es1688->reg_lock, flags); udelay(100); @@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev, snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -EIO; } - return 0; -} -static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus) -{ - gus->joystick_dac = joystick_dac[dev]; + return 0; } static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; - int err; + int error; memset(&id1, 0, sizeof(id1)); memset(&id2, 0, sizeof(id2)); id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + /* reassign AUX to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "Synth Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + /* reassign Master Playback Switch to Synth Playback Switch */ strcpy(id1.name, "Master Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + return 0; } -static int __devinit snd_gusextreme_probe(struct platform_device *pdev) +static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_ess_irqs[] = {5, 9, 10, 7, -1}; - static int possible_ess_dmas[] = {1, 3, 0, -1}; - static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; - static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1}; - int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma; struct snd_card *card; struct snd_gus_card *gus; struct snd_es1688 *es1688; struct snd_opl3 *opl3; - int err; + int error; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; - xgf1_irq = gf1_irq[dev]; - if (xgf1_irq == SNDRV_AUTO_IRQ) { - if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_irq = irq[dev]; - if (xess_irq == SNDRV_AUTO_IRQ) { - if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n"); - err = -EBUSY; - goto out; - } - } - if (mpu_port[dev] == SNDRV_AUTO_PORT) - mpu_port[dev] = 0; - xmpu_irq = mpu_irq[dev]; - if (xmpu_irq > 15) - xmpu_irq = -1; - xgf1_dma = dma1[dev]; - if (xgf1_dma == SNDRV_AUTO_DMA) { - if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_dma = dma8[dev]; - if (xess_dma == SNDRV_AUTO_DMA) { - if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n"); - err = -EBUSY; - goto out; - } - } + if (mpu_port[n] == SNDRV_AUTO_PORT) + mpu_port[n] = 0; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_es1688_create(card, port[dev], mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_es1688_create(card, - possible_ports[i], - mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) + if (mpu_irq[n] > 15) + mpu_irq[n] = -1; + + error = snd_gusextreme_es1688_create(card, dev, n, &es1688); + if (error < 0) goto out; - if (gf1_port[dev] < 0) - gf1_port[dev] = port[dev] + 0x20; - if ((err = snd_gus_create(card, - gf1_port[dev], - xgf1_irq, - xgf1_dma, - -1, - 0, channels[dev], - pcm_channels[dev], 0, - &gus)) < 0) + if (gf1_port[n] < 0) + gf1_port[n] = es1688->port + 0x20; + + error = snd_gusextreme_gus_card_create(card, dev, n, &gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0) + error = snd_gusextreme_detect(gus, es1688); + if (error < 0) goto out; - snd_gusextreme_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) goto out; + error = -ENODEV; if (!gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; + snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not " + "detected at 0x%lx\n", dev->bus_id, gus->gf1.port); goto out; } - if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0) + gus->codec_flag = 1; + + error = snd_es1688_pcm(es1688, 0, NULL); + if (error < 0) goto out; - if ((err = snd_es1688_mixer(es1688)) < 0) + error = snd_es1688_mixer(es1688); + if (error < 0) goto out; snd_component_add(card, "ES1688"); - if (pcm_channels[dev] > 0) { - if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) + + if (pcm_channels[n] > 0) { + error = snd_gf1_pcm_new(gus, 1, 1, NULL); + if (error < 0) goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) + + error = snd_gf1_new_mixer(gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_mixer(es1688)) < 0) + error = snd_gusextreme_mixer(es1688); + if (error < 0) goto out; if (snd_opl3_create(card, es1688->port, es1688->port + 2, - OPL3_HW_OPL3, 0, &opl3) < 0) { - printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port); - } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0) + OPL3_HW_OPL3, 0, &opl3) < 0) + printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n", + dev->bus_id, es1688->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 2, NULL); + if (error < 0) goto out; } - if (es1688->mpu_port >= 0x300 && - (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, - es1688->mpu_port, 0, - xmpu_irq, - IRQF_DISABLED, - NULL)) < 0) - goto out; + if (es1688->mpu_port >= 0x300) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, + es1688->mpu_port, 0, + mpu_irq[n], IRQF_DISABLED, NULL); + if (error < 0) + goto out; + } - sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i", - es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma); + sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, " + "irq %i&%i, dma %i&%i", es1688->port, + gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) + error = snd_card_register(card); + if (error < 0) goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - out: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_gusextreme_remove(struct platform_device *devptr) +static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define GUSEXTREME_DRIVER "snd_gusextreme" - -static struct platform_driver snd_gusextreme_driver = { +static struct isa_driver snd_gusextreme_driver = { + .match = snd_gusextreme_match, .probe = snd_gusextreme_probe, - .remove = __devexit_p(snd_gusextreme_remove), - /* FIXME: suspend/resume */ + .remove = snd_gusextreme_remove, +#if 0 /* FIXME */ + .suspend = snd_gusextreme_suspend, + .resume = snd_gusextreme_resume, +#endif .driver = { - .name = GUSEXTREME_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusextreme_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusextreme_driver); -} - static int __init alsa_card_gusextreme_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusextreme_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSEXTREME_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); -#endif - snd_gusextreme_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS); } static void __exit alsa_card_gusextreme_exit(void) { - snd_gusextreme_unregister_all(); + isa_unregister_driver(&snd_gusextreme_driver); } -module_init(alsa_card_gusextreme_init) -module_exit(alsa_card_gusextreme_exit) +module_init(alsa_card_gusextreme_init); +module_exit(alsa_card_gusextreme_exit); diff --git a/trunk/sound/isa/gus/gusmax.c b/trunk/sound/isa/gus/gusmax.c index d1ad90ca035d..708783d4351f 100644 --- a/trunk/sound/isa/gus/gusmax.c +++ b/trunk/sound/isa/gus/gusmax.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver."); module_param_array(pcm_channels, int, NULL, 0444); MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); -static struct platform_device *devices[SNDRV_CARDS]; - struct snd_gusmax { int irq; struct snd_card *card; @@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card) free_irq(maxcard->irq, (void *)maxcard); } -static int __devinit snd_gusmax_probe(struct platform_device *pdev) +static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev) +{ + return enable[dev]; +} + +static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; int xirq, xdma1, xdma2, err; @@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%i", xdma2); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_card_register(card)) < 0) goto _err; @@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) maxcard->gus = gus; maxcard->cs4231 = cs4231; - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; _err: @@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) return err; } -static int __devexit snd_gusmax_remove(struct platform_device *devptr) +static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -#define GUSMAX_DRIVER "snd_gusmax" +#define DEV_NAME "gusmax" -static struct platform_driver snd_gusmax_driver = { +static struct isa_driver snd_gusmax_driver = { + .match = snd_gusmax_match, .probe = snd_gusmax_probe, .remove = __devexit_p(snd_gusmax_remove), /* FIXME: suspend/resume */ .driver = { - .name = GUSMAX_DRIVER + .name = DEV_NAME }, }; -static void __init_or_module snd_gusmax_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusmax_driver); -} - static int __init alsa_card_gusmax_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusmax_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSMAX_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS MAX soundcard not found or device busy\n"); -#endif - snd_gusmax_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS); } static void __exit alsa_card_gusmax_exit(void) { - snd_gusmax_unregister_all(); + isa_unregister_driver(&snd_gusmax_driver); } module_init(alsa_card_gusmax_init) diff --git a/trunk/sound/isa/gus/interwave.c b/trunk/sound/isa/gus/interwave.c index 4ec2d79431fc..3e4657255536 100644 --- a/trunk/sound/isa/gus/interwave.c +++ b/trunk/sound/isa/gus/interwave.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver."); module_param_array(effect, int, NULL, 0444); MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; - struct snd_interwave { int irq; struct snd_card *card; @@ -138,6 +135,7 @@ struct snd_interwave { #ifdef CONFIG_PNP +static int pnp_registered; static struct pnp_card_device_id snd_interwave_pnpids[] = { #ifndef SNDRV_STB @@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) return 0; } -static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) { struct snd_card *card; int err; @@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device if (! card) return -ENOMEM; - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_interwave_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_interwave_isa_match(struct device *pdev, + unsigned int dev) +{ + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif + return 1; +} + +static int __devinit snd_interwave_isa_probe(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; @@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) - return snd_interwave_nonpnp_probe1(dev, pdev); + return snd_interwave_isa_probe1(dev, pdev); else { static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_interwave_nonpnp_probe1(dev, pdev); + err = snd_interwave_isa_probe1(dev, pdev); if (! err) return 0; } @@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_interwave_driver = { - .probe = snd_interwave_nonpnp_probe, - .remove = __devexit_p(snd_interwave_nonpnp_remove), +static struct isa_driver snd_interwave_driver = { + .match = snd_interwave_isa_match, + .probe = snd_interwave_isa_probe, + .remove = __devexit_p(snd_interwave_isa_remove), /* FIXME: suspend,resume */ .driver = { .name = INTERWAVE_DRIVER @@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = { }; #ifdef CONFIG_PNP -static unsigned int __devinitdata interwave_pnp_devices; - static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - interwave_pnp_devices++; return 0; } @@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_interwave_unregister_all(void) -{ - int i; - - if (pnp_registered) - pnp_unregister_card_driver(&interwave_pnpc_driver); - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_interwave_driver); -} - static int __init alsa_card_interwave_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_interwave_driver)) < 0) + err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(INTERWAVE_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - /* ISA PnP cards */ err = pnp_register_card_driver(&interwave_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += interwave_pnp_devices;; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "InterWave soundcard not found or device busy\n"); #endif - snd_interwave_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_interwave_exit(void) { - snd_interwave_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&interwave_pnpc_driver); +#endif + isa_unregister_driver(&snd_interwave_driver); } module_init(alsa_card_interwave_init) diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index f3db686b1c0c..48743eb85fb6 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver."); module_param_array(opl3sa3_ymode, int, NULL, 0444); MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; static int pnpc_registered; #endif -static unsigned int snd_opl3sa2_devices; /* control ports */ #define OPL3SA2_PM_CTRL 0x01 @@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_opl3sa2_isa_match(struct device *pdev, + unsigned int dev) { - struct snd_card *card; - int err; - int dev = pdev->id; - + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif if (port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify port\n"); - return -EINVAL; + return 0; } if (wss_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify wss_port\n"); - return -EINVAL; + return 0; } if (fm_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify fm_port\n"); - return -EINVAL; + return 0; } if (midi_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify midi_port\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_opl3sa2_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_opl3sa2_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_opl3sa2_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_opl3sa2_suspend(platform_get_drvdata(dev), state); + return snd_opl3sa2_suspend(dev_get_drvdata(dev), state); } -static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev) +static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n) { - return snd_opl3sa2_resume(platform_get_drvdata(dev)); + return snd_opl3sa2_resume(dev_get_drvdata(dev)); } #endif -#define OPL3SA2_DRIVER "snd_opl3sa2" +#define DEV_NAME "opl3sa2" -static struct platform_driver snd_opl3sa2_nonpnp_driver = { - .probe = snd_opl3sa2_nonpnp_probe, - .remove = __devexit( snd_opl3sa2_nonpnp_remove), +static struct isa_driver snd_opl3sa2_isa_driver = { + .match = snd_opl3sa2_isa_match, + .probe = snd_opl3sa2_isa_probe, + .remove = __devexit( snd_opl3sa2_isa_remove), #ifdef CONFIG_PM - .suspend = snd_opl3sa2_nonpnp_suspend, - .resume = snd_opl3sa2_nonpnp_resume, + .suspend = snd_opl3sa2_isa_suspend, + .resume = snd_opl3sa2_isa_resume, #endif .driver = { - .name = OPL3SA2_DRIVER + .name = DEV_NAME }, }; -static void __init_or_module snd_opl3sa2_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); - if (pnp_registered) - pnp_unregister_driver(&opl3sa2_pnp_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); -} - static int __init alsa_card_opl3sa2_init(void) { - int i, err; + int err; - if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; -#ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(OPL3SA2_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - snd_opl3sa2_devices++; - } - #ifdef CONFIG_PNP err = pnp_register_driver(&opl3sa2_pnp_driver); if (!err) @@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void) if (!err) pnpc_registered = 1; #endif - - if (!snd_opl3sa2_devices) { -#ifdef MODULE - snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); -#endif - snd_opl3sa2_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_opl3sa2_exit(void) { - snd_opl3sa2_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&opl3sa2_pnpc_driver); + if (pnp_registered) + pnp_unregister_driver(&opl3sa2_pnp_driver); +#endif + isa_unregister_driver(&snd_opl3sa2_isa_driver); } module_init(alsa_card_opl3sa2_init) diff --git a/trunk/sound/isa/opti9xx/miro.c b/trunk/sound/isa/opti9xx/miro.c index 1dd98375ac85..cd29b30b362e 100644 --- a/trunk/sound/isa/opti9xx/miro.c +++ b/trunk/sound/isa/opti9xx/miro.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -137,10 +137,6 @@ struct snd_miro { static void snd_miro_proc_init(struct snd_miro * miro); -#define DRIVER_NAME "snd-miro" - -static struct platform_device *device; - static char * snd_opti9xx_names[] = { "unkown", "82C928", "82C929", @@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new snd_miro_controls[] = { +static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = { MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER), MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC), MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE), @@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2), /* Equalizer with seven bands (only PCM20) from -12dB up to +12dB on each band */ -static struct snd_kcontrol_new snd_miro_eq_controls[] = { +static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = { MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1), MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2), MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3), @@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6), MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7), }; -static struct snd_kcontrol_new snd_miro_radio_control[] = { +static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = { MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1), }; -static struct snd_kcontrol_new snd_miro_line_control[] = { +static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = { MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1), }; -static struct snd_kcontrol_new snd_miro_preamp_control[] = { +static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Mic Boost", @@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = { .put = snd_miro_put_preamp, }}; -static struct snd_kcontrol_new snd_miro_amp_control[] = { +static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Line Boost", @@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = { .put = snd_miro_put_amp, }}; -static struct snd_kcontrol_new snd_miro_capture_control[] = { +static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Capture Switch", @@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = { .put = snd_miro_put_capture, }}; -static unsigned char aci_init_values[][2] __initdata = { +static unsigned char aci_init_values[][2] __devinitdata = { { ACI_SET_MUTE, 0x00 }, { ACI_SET_POWERAMP, 0x00 }, { ACI_SET_PREAMP, 0x00 }, @@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = { { ACI_SET_MASTER + 1, 0x20 }, }; -static int __init snd_set_aci_init_values(struct snd_miro *miro) +static int __devinit snd_set_aci_init_values(struct snd_miro *miro) { int idx, error; @@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size) return -1; } -static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware) +static int __devinit snd_miro_init(struct snd_miro *chip, + unsigned short hardware) { static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; @@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry, snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); } -static void __init snd_miro_proc_init(struct snd_miro * miro) +static void __devinit snd_miro_proc_init(struct snd_miro * miro) { struct snd_info_entry *entry; @@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro) * Init */ -static int __init snd_miro_configure(struct snd_miro *chip) +static int __devinit snd_miro_configure(struct snd_miro *chip) { unsigned char wss_base_bits; unsigned char irq_bits; @@ -1131,7 +1128,8 @@ static int __init snd_miro_configure(struct snd_miro *chip) return 0; } -static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip) +static int __devinit snd_card_miro_detect(struct snd_card *card, + struct snd_miro *chip) { int i, err; unsigned char value; @@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c return -ENODEV; } -static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro) +static int __devinit snd_card_miro_aci_detect(struct snd_card *card, + struct snd_miro * miro) { unsigned char regval; int i; @@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card) release_and_free_resource(miro->res_mc_base); } -static int __init snd_miro_probe(struct platform_device *devptr) +static int __devinit snd_miro_match(struct device *devptr, unsigned int n) +{ + return 1; +} + +static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) { static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1}; @@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr) return error; } - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((error = snd_card_register(card))) { snd_card_free(card); return error; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devexit snd_miro_remove(struct platform_device *devptr) +static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_miro_driver = { +#define DEV_NAME "miro" + +static struct isa_driver snd_miro_driver = { + .match = snd_miro_match, .probe = snd_miro_probe, .remove = __devexit_p(snd_miro_remove), /* FIXME: suspend/resume */ .driver = { - .name = DRIVER_NAME + .name = DEV_NAME }, }; static int __init alsa_card_miro_init(void) { - int error; - - if ((error = platform_driver_register(&snd_miro_driver)) < 0) - return error; - device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (! IS_ERR(device)) { - if (platform_get_drvdata(device)) - return 0; - platform_device_unregister(device); - } -#ifdef MODULE - printk(KERN_ERR "no miro soundcard found\n"); -#endif - platform_driver_unregister(&snd_miro_driver); - return PTR_ERR(device); + return isa_register_driver(&snd_miro_driver, 1); } static void __exit alsa_card_miro_exit(void) { - platform_device_unregister(device); - platform_driver_unregister(&snd_miro_driver); + isa_unregister_driver(&snd_miro_driver); } module_init(alsa_card_miro_init) diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index df227377c333..60c120ffb9de 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -259,7 +259,6 @@ struct snd_opti9xx { }; static int snd_opti9xx_pnp_is_probed; -static struct platform_device *snd_opti9xx_platform_device; #ifdef CONFIG_PNP @@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids); #endif /* CONFIG_PNP */ #ifdef OPTi93X -#define DRIVER_NAME "snd-card-opti93x" +#define DEV_NAME "opti93x" #else -#define DRIVER_NAME "snd-card-opti92x" -#endif /* OPTi93X */ +#define DEV_NAME "opti92x" +#endif static char * snd_opti9xx_names[] = { "unkown", @@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = { }; -static long __init snd_legacy_find_free_ioport(long *port_table, long size) +static long __devinit snd_legacy_find_free_ioport(long *port_table, long size) { while (*port_table != -1) { if (request_region(*port_table, size, "ALSA test")) { @@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size) return -1; } -static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware) +static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, + unsigned short hardware) { static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; @@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) -static int __init snd_opti9xx_configure(struct snd_opti9xx *chip) +static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) { unsigned char wss_base_bits; unsigned char irq_bits; @@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == chip->playback_substream) { what |= OPTi93X_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); @@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip, } codec->dma2 = chip->dma2; - if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) { + if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) { snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); snd_opti93x_free(codec); return -EBUSY; @@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ return change; } -static struct snd_kcontrol_new snd_opti93x_controls[] = { +static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = { OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1), @@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip) #endif /* OPTi93X */ -static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip) +static int __devinit snd_card_opti9xx_detect(struct snd_card *card, + struct snd_opti9xx *chip) { int i, err; @@ -1676,8 +1675,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti } #ifdef CONFIG_PNP -static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card, - const struct pnp_card_device_id *pid) +static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, + struct pnp_card_link *card, + const struct pnp_card_device_id *pid) { struct pnp_dev *pdev; struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); @@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) release_and_free_resource(chip->res_mc_base); } -static int __init snd_opti9xx_probe(struct snd_card *card) +static int __devinit snd_opti9xx_probe(struct snd_card *card) { static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; int error; @@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void) return card; } -static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) +static int __devinit snd_opti9xx_isa_match(struct device *devptr, + unsigned int dev) +{ + if (snd_opti9xx_pnp_is_probed) + return 0; + if (isapnp) + return 0; + return 1; +} + +static int __devinit snd_opti9xx_isa_probe(struct device *devptr, + unsigned int dev) { struct snd_card *card; int error; @@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}}; #endif /* CS4231 || OPTi93X */ - if (snd_opti9xx_pnp_is_probed) - return -EBUSY; - if (mpu_port == SNDRV_AUTO_PORT) { if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) { snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); @@ -1984,34 +1992,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) snd_card_free(card); return error; } - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((error = snd_opti9xx_probe(card)) < 0) { snd_card_free(card); return error; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_opti9xx_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_opti9xx_driver = { - .probe = snd_opti9xx_nonpnp_probe, - .remove = __devexit_p(snd_opti9xx_nonpnp_remove), +static struct isa_driver snd_opti9xx_driver = { + .match = snd_opti9xx_isa_match, + .probe = snd_opti9xx_isa_probe, + .remove = __devexit_p(snd_opti9xx_isa_remove), /* FIXME: suspend/resume */ .driver = { - .name = DRIVER_NAME + .name = DEV_NAME }, }; #ifdef CONFIG_PNP -static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) +static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) { struct snd_card *card; int error, hw; @@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { }; #endif -#ifdef CONFIG_PNP -#define is_isapnp_selected() isapnp -#else -#define is_isapnp_selected() 0 -#endif #ifdef OPTi93X #define CHIP_NAME "82C93x" #else @@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { static int __init alsa_card_opti9xx_init(void) { - int error; - struct platform_device *device; - #ifdef CONFIG_PNP pnp_register_card_driver(&opti9xx_pnpc_driver); if (snd_opti9xx_pnp_is_probed) return 0; #endif - if (! is_isapnp_selected()) { - error = platform_driver_register(&snd_opti9xx_driver); - if (error < 0) - return error; - device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (!IS_ERR(device)) { - if (platform_get_drvdata(device)) { - snd_opti9xx_platform_device = device; - return 0; - } - platform_device_unregister(device); - } - platform_driver_unregister(&snd_opti9xx_driver); - } -#ifdef CONFIG_PNP - pnp_unregister_card_driver(&opti9xx_pnpc_driver); -#endif -#ifdef MODULE - printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); -#endif - return -ENODEV; + return isa_register_driver(&snd_opti9xx_driver, 1); } static void __exit alsa_card_opti9xx_exit(void) { if (!snd_opti9xx_pnp_is_probed) { - platform_device_unregister(snd_opti9xx_platform_device); - platform_driver_unregister(&snd_opti9xx_driver); + isa_unregister_driver(&snd_opti9xx_driver); + return; } #ifdef CONFIG_PNP pnp_unregister_card_driver(&opti9xx_pnpc_driver); diff --git a/trunk/sound/isa/sb/sb16.c b/trunk/sound/isa/sb/sb16.c index d64e67f2bafa..2a19b0a39eda 100644 --- a/trunk/sound/isa/sb/sb16.c +++ b/trunk/sound/isa/sb/sb16.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444); MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); #endif -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; #endif @@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card) } #endif -static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) { struct snd_card_sb16 *acard; struct snd_card *card; @@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev awe_port[dev] = port[dev] + 0x400; #endif - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, pdev); if ((err = snd_sb16_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev) +{ + return enable[dev] && !is_isapnp_selected(dev); +} + +static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas8[] = {1, 3, 0, -1}; @@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) - return snd_sb16_nonpnp_probe1(dev, pdev); + return snd_sb16_isa_probe1(dev, pdev); else { static int possible_ports[] = {0x220, 0x240, 0x260, 0x280}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_sb16_nonpnp_probe1(dev, pdev); + err = snd_sb16_isa_probe1(dev, pdev); if (! err) return 0; } @@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_sb16_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_sb16_suspend(platform_get_drvdata(dev), state); + return snd_sb16_suspend(dev_get_drvdata(dev), state); } -static int snd_sb16_nonpnp_resume(struct platform_device *dev) +static int snd_sb16_isa_resume(struct device *dev, unsigned int n) { - return snd_sb16_resume(platform_get_drvdata(dev)); + return snd_sb16_resume(dev_get_drvdata(dev)); } #endif #ifdef SNDRV_SBAWE -#define SND_SB16_DRIVER "snd_sbawe" +#define DEV_NAME "sbawe" #else -#define SND_SB16_DRIVER "snd_sb16" +#define DEV_NAME "sb16" #endif -static struct platform_driver snd_sb16_nonpnp_driver = { - .probe = snd_sb16_nonpnp_probe, - .remove = __devexit_p(snd_sb16_nonpnp_remove), +static struct isa_driver snd_sb16_isa_driver = { + .match = snd_sb16_isa_match, + .probe = snd_sb16_isa_probe, + .remove = __devexit_p(snd_sb16_isa_remove), #ifdef CONFIG_PM - .suspend = snd_sb16_nonpnp_suspend, - .resume = snd_sb16_nonpnp_resume, + .suspend = snd_sb16_isa_suspend, + .resume = snd_sb16_isa_resume, #endif .driver = { - .name = SND_SB16_DRIVER + .name = DEV_NAME }, }; #ifdef CONFIG_PNP -static unsigned int __devinitdata sb16_pnp_devices; - static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - sb16_pnp_devices++; return 0; } @@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_sb16_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&sb16_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_sb16_nonpnp_driver); -} - static int __init alsa_card_sb16_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(SND_SB16_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } #ifdef CONFIG_PNP /* PnP cards at last */ err = pnp_register_card_driver(&sb16_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += sb16_pnp_devices; - } -#endif - - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n"); -#ifdef SNDRV_SBAWE_EMU8000 - snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n"); -#else - snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); #endif -#endif - snd_sb16_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_sb16_exit(void) { - snd_sb16_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&sb16_pnpc_driver); +#endif + isa_unregister_driver(&snd_sb16_isa_driver); } module_init(alsa_card_sb16_init) diff --git a/trunk/sound/isa/sb/sb16_csp.c b/trunk/sound/isa/sb/sb16_csp.c index 3d9d7e0107ca..b279f2308aef 100644 --- a/trunk/sound/isa/sb/sb16_csp.c +++ b/trunk/sound/isa/sb/sb16_csp.c @@ -36,6 +36,13 @@ MODULE_AUTHOR("Uros Bizjak "); MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); MODULE_LICENSE("GPL"); +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("sb16/mulaw_main.csp"); +MODULE_FIRMWARE("sb16/alaw_main.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); +#endif #ifdef SNDRV_LITTLE_ENDIAN #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) @@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) */ static void snd_sb_csp_free(struct snd_hwdep *hwdep) { +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL int i; +#endif struct snd_sb_csp *p = hwdep->private_data; if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) release_firmware(p->csp_programs[i]); +#endif kfree(p); } } @@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use return err; } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL #include "sb16_csp_codecs.h" static const struct firmware snd_sb_csp_static_programs[] = { @@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) "sb16/ima_adpcm_capture.csp", }; const struct firmware *program; - int err; BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); program = p->csp_programs[index]; if (!program) { - err = request_firmware(&program, names[index], - p->chip->card->dev); - if (err >= 0) - p->csp_programs[index] = program; - else { -#ifdef FIRMWARE_IN_THE_KERNEL - program = &snd_sb_csp_static_programs[index]; +#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL + program = &snd_sb_csp_static_programs[index]; #else + int err = request_firmware(&program, names[index], + p->chip->card->dev); + if (err < 0) return err; #endif - } + p->csp_programs[index] = program; } return snd_sb_csp_load(p, program->data, program->size, flags); } diff --git a/trunk/sound/isa/sb/sb8.c b/trunk/sound/isa/sb/sb8.c index be1e83e6dea3..a1b3786b391e 100644 --- a/trunk/sound/isa/sb/sb8.c +++ b/trunk/sound/isa/sb/sb8.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver."); module_param_array(dma8, int, NULL, 0444); MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); -static struct platform_device *devices[SNDRV_CARDS]; - struct snd_sb8 { struct resource *fm_res; /* used to block FM i/o region for legacy cards */ struct snd_sb *chip; @@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card) release_and_free_resource(acard->fm_res); } -static int __devinit snd_sb8_probe(struct platform_device *pdev) +static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev) +{ + if (!enable[dev]) + return 0; + if (irq[dev] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); + return 0; + } + if (dma8[dev] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id); + return 0; + } + return 1; +} + +static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; struct snd_sb *chip; struct snd_card *card; struct snd_sb8 *acard; @@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) chip->port, irq[dev], dma8[dev]); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_card_register(card)) < 0) goto _err; - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; _err: @@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) return err; } -static int __devexit snd_sb8_remove(struct platform_device *pdev) +static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev) { - snd_card_free(platform_get_drvdata(pdev)); - platform_set_drvdata(pdev, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) +static int snd_sb8_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - struct snd_card *card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_sb8 *acard = card->private_data; struct snd_sb *chip = acard->chip; @@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) return 0; } -static int snd_sb8_resume(struct platform_device *dev) +static int snd_sb8_resume(struct device *dev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_sb8 *acard = card->private_data; struct snd_sb *chip = acard->chip; @@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev) } #endif -#define SND_SB8_DRIVER "snd_sb8" +#define DEV_NAME "sb8" -static struct platform_driver snd_sb8_driver = { +static struct isa_driver snd_sb8_driver = { + .match = snd_sb8_match, .probe = snd_sb8_probe, .remove = __devexit_p(snd_sb8_remove), #ifdef CONFIG_PM @@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = { .resume = snd_sb8_resume, #endif .driver = { - .name = SND_SB8_DRIVER + .name = DEV_NAME }, }; -static void __init_or_module snd_sb8_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_sb8_driver); -} - static int __init alsa_card_sb8_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_sb8_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_SB8_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n"); -#endif - snd_sb8_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS); } static void __exit alsa_card_sb8_exit(void) { - snd_sb8_unregister_all(); + isa_unregister_driver(&snd_sb8_driver); } module_init(alsa_card_sb8_init) diff --git a/trunk/sound/isa/sgalaxy.c b/trunk/sound/isa/sgalaxy.c index 4fcd0f4e868c..922519def099 100644 --- a/trunk/sound/isa/sgalaxy.c +++ b/trunk/sound/isa/sgalaxy.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver."); module_param_array(dma1, int, NULL, 0444); MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); -static struct platform_device *devices[SNDRV_CARDS]; - #define SGALAXY_AUXC_LEFT 18 #define SGALAXY_AUXC_RIGHT 19 @@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port) return 0; } -static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val) +static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port, + unsigned char val) { int i; @@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id) return IRQ_NONE; } -static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) +static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) { static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20, -1, -1, -1, -1}; @@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) return 0; } -static int __init snd_sgalaxy_detect(int dev, int irq, int dma) +static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma) { #if 0 snd_printdd(PFX "switching to WSS mode\n"); @@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) }; -static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) +static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) return 0; } -static int __init snd_sgalaxy_probe(struct platform_device *devptr) +static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev) { - int dev = devptr->id; - static int possible_irqs[] = {7, 9, 10, 11, -1}; - static int possible_dmas[] = {1, 3, 0, -1}; - int err, xirq, xdma1; - struct snd_card *card; - struct snd_ad1848 *chip; - + if (!enable[dev]) + return 0; if (sbport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify SB port\n"); - return -EINVAL; + return 0; } if (wssport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify WSS port\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) +{ + static int possible_irqs[] = {7, 9, 10, 11, -1}; + static int possible_dmas[] = {1, 3, 0, -1}; + int err, xirq, xdma1; + struct snd_card *card; + struct snd_ad1848 *chip; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; @@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", wssport[dev], xirq, xdma1); - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_card_register(card)) < 0) goto _err; - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; _err: @@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) return err; } -static int __devexit snd_sgalaxy_remove(struct platform_device *devptr) +static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) +static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n, + pm_message_t state) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(pdev); struct snd_ad1848 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); @@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int snd_sgalaxy_resume(struct platform_device *pdev) +static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(pdev); struct snd_ad1848 *chip = card->private_data; chip->resume(chip); @@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev) } #endif -#define SND_SGALAXY_DRIVER "snd_sgalaxy" +#define DEV_NAME "sgalaxy" -static struct platform_driver snd_sgalaxy_driver = { +static struct isa_driver snd_sgalaxy_driver = { + .match = snd_sgalaxy_match, .probe = snd_sgalaxy_probe, .remove = __devexit_p(snd_sgalaxy_remove), #ifdef CONFIG_PM @@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = { .resume = snd_sgalaxy_resume, #endif .driver = { - .name = SND_SGALAXY_DRIVER + .name = DEV_NAME }, }; -static void __init_or_module snd_sgalaxy_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_sgalaxy_driver); -} - static int __init alsa_card_sgalaxy_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_sgalaxy_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_SGALAXY_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); -#endif - snd_sgalaxy_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS); } static void __exit alsa_card_sgalaxy_exit(void) { - snd_sgalaxy_unregister_all(); + isa_unregister_driver(&snd_sgalaxy_driver); } module_init(alsa_card_sgalaxy_init) diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index b1f25823c652..08c14978558c 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver."); module_param_array(dma, int, NULL, 0444); MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered; static struct pnp_card_device_id sscape_pnpids[] = { @@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) } -static int __devinit snd_sscape_probe(struct platform_device *pdev) +static int __devinit snd_sscape_match(struct device *pdev, unsigned int i) +{ + /* + * Make sure we were given ALL of the other parameters. + */ + if (port[i] == SNDRV_AUTO_PORT) + return 0; + + if (irq[i] == SNDRV_AUTO_IRQ || + mpu_irq[i] == SNDRV_AUTO_IRQ || + dma[i] == SNDRV_AUTO_DMA) { + printk(KERN_INFO + "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); + return 0; + } + + return 1; +} + +static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; struct snd_card *card; int ret; @@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev) ret = create_sscape(dev, &card); if (ret < 0) return ret; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((ret = snd_card_register(card)) < 0) { printk(KERN_ERR "sscape: Failed to register sound card\n"); return ret; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_sscape_remove(struct platform_device *devptr) +static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -#define SSCAPE_DRIVER "snd_sscape" +#define DEV_NAME "sscape" -static struct platform_driver snd_sscape_driver = { +static struct isa_driver snd_sscape_driver = { + .match = snd_sscape_match, .probe = snd_sscape_probe, .remove = __devexit_p(snd_sscape_remove), /* FIXME: suspend/resume */ .driver = { - .name = SSCAPE_DRIVER + .name = DEV_NAME }, }; @@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module sscape_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&sscape_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_sscape_driver); -} - -static int __init sscape_manual_probe(void) -{ - struct platform_device *device; - int i, ret; - - ret = platform_driver_register(&snd_sscape_driver); - if (ret < 0) - return ret; - - for (i = 0; i < SNDRV_CARDS; ++i) { - /* - * We do NOT probe for ports. - * If we're not given a port number for this - * card then we completely ignore this line - * of parameters. - */ - if (port[i] == SNDRV_AUTO_PORT) - continue; - - /* - * Make sure we were given ALL of the other parameters. - */ - if (irq[i] == SNDRV_AUTO_IRQ || - mpu_irq[i] == SNDRV_AUTO_IRQ || - dma[i] == SNDRV_AUTO_DMA) { - printk(KERN_INFO - "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); - sscape_unregister_all(); - return -ENXIO; - } - - /* - * This cards looks OK ... - */ - device = platform_device_register_simple(SSCAPE_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - } - return 0; -} - -static void sscape_exit(void) -{ - sscape_unregister_all(); -} - - static int __init sscape_init(void) { int ret; @@ -1462,7 +1413,7 @@ static int __init sscape_init(void) * of allocating cards, because the operator is * S-P-E-L-L-I-N-G it out for us... */ - ret = sscape_manual_probe(); + ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS); if (ret < 0) return ret; #ifdef CONFIG_PNP @@ -1472,5 +1423,14 @@ static int __init sscape_init(void) return 0; } +static void __exit sscape_exit(void) +{ +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&sscape_pnpc_driver); +#endif + isa_unregister_driver(&snd_sscape_driver); +} + module_init(sscape_init); module_exit(sscape_exit); diff --git a/trunk/sound/isa/wavefront/wavefront.c b/trunk/sound/isa/wavefront/wavefront.c index e2fdd5fd39d0..75673f723857 100644 --- a/trunk/sound/isa/wavefront/wavefront.c +++ b/trunk/sound/isa/wavefront/wavefront.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +#ifdef CONFIG_PNP static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +#endif static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ @@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #."); module_param_array(use_cs4232_midi, bool, NULL, 0444); MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered; @@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_wavefront_isa_match(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; - struct snd_card *card; - int err; - + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { snd_printk("specify CS4232 port\n"); - return -EINVAL; + return 0; } if (ics2115_port[dev] == SNDRV_AUTO_PORT) { snd_printk("specify ICS2115 port\n"); - return -ENODEV; + return 0; } + return 1; +} + +static int __devinit snd_wavefront_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_wavefront_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_wavefront_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_wavefront_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -#define WAVEFRONT_DRIVER "snd_wavefront" +#define DEV_NAME "wavefront" -static struct platform_driver snd_wavefront_driver = { - .probe = snd_wavefront_nonpnp_probe, - .remove = __devexit_p(snd_wavefront_nonpnp_remove), +static struct isa_driver snd_wavefront_driver = { + .match = snd_wavefront_isa_match, + .probe = snd_wavefront_isa_probe, + .remove = __devexit_p(snd_wavefront_isa_remove), /* FIXME: suspend, resume */ .driver = { - .name = WAVEFRONT_DRIVER + .name = DEV_NAME }, }; #ifdef CONFIG_PNP -static unsigned int __devinitdata wavefront_pnp_devices; - static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - wavefront_pnp_devices++; return 0; } @@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_wavefront_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&wavefront_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_wavefront_driver); -} - static int __init alsa_card_wavefront_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) + err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; -#ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(WAVEFRONT_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_card_driver(&wavefront_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += wavefront_pnp_devices; - } -#endif - - if (!cards) { -#ifdef MODULE - printk (KERN_ERR "No WaveFront cards found or devices busy\n"); #endif - snd_wavefront_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_wavefront_exit(void) { - snd_wavefront_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&wavefront_pnpc_driver); +#endif + isa_unregister_driver(&snd_wavefront_driver); } module_init(alsa_card_wavefront_init) diff --git a/trunk/sound/isa/wavefront/wavefront_fx.c b/trunk/sound/isa/wavefront/wavefront_fx.c index 15331ed88194..fc95a870f690 100644 --- a/trunk/sound/isa/wavefront/wavefront_fx.c +++ b/trunk/sound/isa/wavefront/wavefront_fx.c @@ -35,9 +35,7 @@ #define WAIT_IDLE 0xff -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL #include "yss225.c" static const struct firmware yss225_registers_firmware = { .data = (u8 *)yss225_registers, @@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) { unsigned int i; int err; - const struct firmware *firmware; + const struct firmware *firmware = NULL; if (dev->fx_initialized) return 0; +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL + firmware = &yss225_registers_firmware; +#else err = request_firmware(&firmware, "yamaha/yss225_registers.bin", dev->card->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - firmware = &yss225_registers_firmware; -#else err = -1; goto out; -#endif } +#endif for (i = 0; i + 1 < firmware->size; i += 2) { if (firmware->data[i] >= 8 && firmware->data[i] < 16) { @@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) err = 0; out: -#ifdef FIRMWARE_IN_THE_KERNEL - if (firmware != &yss225_registers_firmware) +#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL + release_firmware(firmware); #endif - release_firmware(firmware); return err; } + +#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("yamaha/yss225_registers.bin"); +#endif diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 1bcfb3aac18d..61e35ecc57b8 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -576,7 +576,7 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER + select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -584,10 +584,19 @@ config SND_KORG1212 To compile this driver as a module, choose M here: the module will be called snd-korg1212. +config SND_KORG1212_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Korg1212 driver" + depends on SND_KORG1212 + default y + help + Say Y here to include the static firmware built in the kernel + for the Korg1212 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND - select FW_LOADER + select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL select SND_AC97_CODEC help Say Y here to include support for soundcards based on ESS Maestro 3 @@ -596,6 +605,15 @@ config SND_MAESTRO3 To compile this driver as a module, choose M here: the module will be called snd-maestro3. +config SND_MAESTRO3_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Maestro3 driver" + depends on SND_MAESTRO3 + default y + help + Say Y here to include the static firmware built in the kernel + for the Maestro3 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_MIXART tristate "Digigram miXart" depends on SND @@ -737,7 +755,7 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER + select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -748,6 +766,15 @@ config SND_YMFPCI To compile this driver as a module, choose M here: the module will be called snd-ymfpci. +config SND_YMFPCI_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for YMFPCI driver" + depends on SND_YMFPCI + default y + help + Say Y here to include the static firmware built in the kernel + for the YMFPCI driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_AC97_POWER_SAVE bool "AC97 Power-Saving Mode" depends on SND_AC97_CODEC && EXPERIMENTAL diff --git a/trunk/sound/pci/ac97/Makefile b/trunk/sound/pci/ac97/Makefile index 3c3222122d8b..f5d471896b95 100644 --- a/trunk/sound/pci/ac97/Makefile +++ b/trunk/sound/pci/ac97/Makefile @@ -3,7 +3,7 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o +snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ifneq ($(CONFIG_PROC_FS),) snd-ac97-codec-objs += ac97_proc.o diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 3bfb2102fc5d..bbed644bf9c5 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -35,9 +35,9 @@ #include #include #include -#include "ac97_local.h" #include "ac97_id.h" -#include "ac97_patch.h" + +#include "ac97_patch.c" MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); @@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns * Controls */ -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return 0; } -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) } /* volume and switch controls */ -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 16) & 0xff; int shift = (kcontrol->private_value >> 8) & 0x0f; @@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info return 0; } -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value return 0; } -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]), AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) }; -const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { +static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0), AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0) }; @@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return change; } -const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { +static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha } } -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) { unsigned short mask, val, orig, res; @@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x) return x; } -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97) +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97) { struct snd_kcontrol_new template; memcpy(&template, _template, sizeof(template)); @@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix) } /* remove the control with the given name and optional suffix */ -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix) +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix) { struct snd_ctl_elem_id id; memset(&id, 0, sizeof(id)); @@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co } /* rename the control with the given name and optional suffix */ -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix) +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix) { struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); if (kctl) { @@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, } /* rename both Volume and Switch controls - don't check the return value */ -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst) +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst) { snd_ac97_rename_ctl(ac97, src, dst, "Switch"); snd_ac97_rename_ctl(ac97, src, dst, "Volume"); } /* swap controls */ -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix) +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix) { struct snd_kcontrol *kctl1, *kctl2; kctl1 = ctl_find(ac97, s1, suffix); diff --git a/trunk/sound/pci/ac97/ac97_local.h b/trunk/sound/pci/ac97/ac97_local.h index a6244c720a1d..78745c5c6df8 100644 --- a/trunk/sound/pci/ac97/ac97_local.h +++ b/trunk/sound/pci/ac97/ac97_local.h @@ -22,59 +22,8 @@ * */ -#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24)) -#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) -#define AC97_SINGLE(xname, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } -#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } -#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } - -/* enum control */ -struct ac97_enum { - unsigned char reg; - unsigned char shift_l; - unsigned char shift_r; - unsigned short mask; - const char **texts; -}; - -#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ -{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ - .mask = xmask, .texts = xtexts } -#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ - AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) -#define AC97_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \ - .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ - .private_value = (unsigned long)&xenum } - -/* ac97_codec.c */ -extern const struct snd_kcontrol_new snd_ac97_controls_3d[]; -extern const struct snd_kcontrol_new snd_ac97_controls_spdif[]; -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97); -void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem); -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix); -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix); -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix); -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst); -void snd_ac97_restore_status(struct snd_ac97 *ac97); -void snd_ac97_restore_iec958(struct snd_ac97 *ac97); -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - +void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, + int modem); int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index b188a4df58cb..3eac0f86266c 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -23,20 +23,8 @@ * */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "ac97_patch.h" -#include "ac97_id.h" #include "ac97_local.h" +#include "ac97_patch.h" /* * Chip specific initialization @@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { .build_post_spdif = patch_yamaha_ymf753_post_spdif }; -int patch_yamaha_ymf753(struct snd_ac97 * ac97) +static int patch_yamaha_ymf753(struct snd_ac97 * ac97) { /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. This chip has nonstandard and extended behaviour with regard to its S/PDIF output. @@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { .build_specific = patch_wolfson_wm9703_specific, }; -int patch_wolfson03(struct snd_ac97 * ac97) +static int patch_wolfson03(struct snd_ac97 * ac97) { ac97->build_ops = &patch_wolfson_wm9703_ops; return 0; @@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { .build_specific = patch_wolfson_wm9704_specific, }; -int patch_wolfson04(struct snd_ac97 * ac97) +static int patch_wolfson04(struct snd_ac97 * ac97) { /* WM9704M/9704Q */ ac97->build_ops = &patch_wolfson_wm9704_ops; @@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { .build_specific = patch_wolfson_wm9705_specific, }; -int patch_wolfson05(struct snd_ac97 * ac97) +static int patch_wolfson05(struct snd_ac97 * ac97) { /* WM9705, WM9710 */ ac97->build_ops = &patch_wolfson_wm9705_ops; @@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { .build_specific = patch_wolfson_wm9711_specific, }; -int patch_wolfson11(struct snd_ac97 * ac97) +static int patch_wolfson11(struct snd_ac97 * ac97) { /* WM9711, WM9712 */ ac97->build_ops = &patch_wolfson_wm9711_ops; @@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { #endif }; -int patch_wolfson13(struct snd_ac97 * ac97) +static int patch_wolfson13(struct snd_ac97 * ac97) { /* WM9713, WM9714 */ ac97->build_ops = &patch_wolfson_wm9713_ops; @@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97) /* * Tritech codec */ -int patch_tritech_tr28028(struct snd_ac97 * ac97) +static int patch_tritech_tr28028(struct snd_ac97 * ac97) { snd_ac97_write_cache(ac97, 0x26, 0x0300); snd_ac97_write_cache(ac97, 0x26, 0x0000); @@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { .build_specific = patch_sigmatel_stac97xx_specific }; -int patch_sigmatel_stac9700(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9700(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; return 0; @@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { .build_specific = patch_sigmatel_stac9708_specific }; -int patch_sigmatel_stac9708(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9708(struct snd_ac97 * ac97) { unsigned int codec72, codec6c; @@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9721(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9721(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { @@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9744(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9744(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9756(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { .build_specific = patch_sigmatel_stac9758_specific }; -int patch_sigmatel_stac9758(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9758(struct snd_ac97 * ac97) { static unsigned short regs[4] = { AC97_SIGMATEL_OUTSEL, @@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = { .build_spdif = patch_cirrus_build_spdif }; -int patch_cirrus_spdif(struct snd_ac97 * ac97) +static int patch_cirrus_spdif(struct snd_ac97 * ac97) { /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* @@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97) return 0; } -int patch_cirrus_cs4299(struct snd_ac97 * ac97) +static int patch_cirrus_cs4299(struct snd_ac97 * ac97) { /* force the detection of PC Beep */ ac97->flags |= AC97_HAS_PC_BEEP; @@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = { .build_spdif = patch_conexant_build_spdif }; -int patch_conexant(struct snd_ac97 * ac97) +static int patch_conexant(struct snd_ac97 * ac97) { ac97->build_ops = &patch_conexant_ops; ac97->flags |= AC97_CX_SPDIF; @@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97) return 0; } -int patch_cx20551(struct snd_ac97 *ac97) +static int patch_cx20551(struct snd_ac97 *ac97) { snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); return 0; @@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = { { } /* terminator */ }; -int patch_ad1819(struct snd_ac97 * ac97) +static int patch_ad1819(struct snd_ac97 * ac97) { unsigned short scfg; @@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = { #endif }; -int patch_ad1881(struct snd_ac97 * ac97) +static int patch_ad1881(struct snd_ac97 * ac97) { static const char cfg_idxs[3][2] = { {2, 1}, @@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = { #endif }; -int patch_ad1885(struct snd_ac97 * ac97) +static int patch_ad1885(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* This is required to deal with the Intel D815EEAL2 */ @@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = { #endif }; -int patch_ad1886(struct snd_ac97 * ac97) +static int patch_ad1886(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* Presario700 workaround */ @@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); } -int patch_ad1981a(struct snd_ac97 *ac97) +static int patch_ad1981a(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981a_build_ops; @@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = { #endif }; -int patch_ad1981b(struct snd_ac97 *ac97) +static int patch_ad1981b(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981b_build_ops; @@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1888(struct snd_ac97 * ac97) +static int patch_ad1888(struct snd_ac97 * ac97) { unsigned short misc; @@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1980(struct snd_ac97 * ac97) +static int patch_ad1980(struct snd_ac97 * ac97) { patch_ad1888(ac97); ac97->build_ops = &patch_ad1980_build_ops; @@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = { .update_jacks = ad1985_update_jacks, }; -int patch_ad1985(struct snd_ac97 * ac97) +static int patch_ad1985(struct snd_ac97 * ac97) { unsigned short misc; @@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = { .update_jacks = ad1986_update_jacks, }; -int patch_ad1986(struct snd_ac97 * ac97) +static int patch_ad1986(struct snd_ac97 * ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1986_build_ops; @@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = { .update_jacks = alc650_update_jacks }; -int patch_alc650(struct snd_ac97 * ac97) +static int patch_alc650(struct snd_ac97 * ac97) { unsigned short val; @@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = { .update_jacks = alc655_update_jacks }; -int patch_alc655(struct snd_ac97 * ac97) +static int patch_alc655(struct snd_ac97 * ac97) { unsigned int val; @@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97) (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ ac97->subsystem_device == 0x0161 || /* LG K1 Express */ ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ + ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */ ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ else @@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = { .update_jacks = alc850_update_jacks }; -int patch_alc850(struct snd_ac97 *ac97) +static int patch_alc850(struct snd_ac97 *ac97) { ac97->build_ops = &patch_alc850_ops; @@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = { .update_jacks = cm9738_update_jacks }; -int patch_cm9738(struct snd_ac97 * ac97) +static int patch_cm9738(struct snd_ac97 * ac97) { ac97->build_ops = &patch_cm9738_ops; /* FIXME: can anyone confirm below? */ @@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = { .update_jacks = cm9739_update_jacks }; -int patch_cm9739(struct snd_ac97 * ac97) +static int patch_cm9739(struct snd_ac97 * ac97) { unsigned short val; @@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = { .update_jacks = cm9761_update_jacks }; -int patch_cm9761(struct snd_ac97 *ac97) +static int patch_cm9761(struct snd_ac97 *ac97) { unsigned short val; @@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = { .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ }; -int patch_cm9780(struct snd_ac97 *ac97) +static int patch_cm9780(struct snd_ac97 *ac97) { unsigned short val; @@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = { .build_specific = patch_vt1616_specific }; -int patch_vt1616(struct snd_ac97 * ac97) +static int patch_vt1616(struct snd_ac97 * ac97) { ac97->build_ops = &patch_vt1616_ops; return 0; @@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97) /* * VT1617A codec */ + +/* + * unfortunately, the vt1617a stashes the twiddlers required for + * nooding the i/o jacks on 2 different regs. * thameans that we cant + * use the easy way provided by AC97_ENUM_DOUBLE() we have to write + * are own funcs. + * + * NB: this is absolutely and utterly different from the vt1618. dunno + * about the 1616. + */ + +/* copied from ac97_surround_jack_mode_info() */ +static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + /* ordering in this list reflects vt1617a docs for Reg 20 and + * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51 + * is SM51EN *AND* it's Bit14, not Bit15 so the table is very + * counter-intuitive */ + + static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", + "Surr LFE/C Mic3", "LineIn LFE/C Mic3", + "LineIn Mic2", "LineIn Mic2 Mic1", + "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; + return ac97_enum_text_info(kcontrol, uinfo, texts, 8); +} + +static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + /* grab our desirec bits, then mash them together in a manner + * consistent with Table 6 on page 17 in the 1617a docs */ + + usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; + usMS = snd_ac97_read(pac97, 0x20) >> 8; + + ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS; + + return 0; +} + +static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS, usReg; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + usSM51 = ucontrol->value.enumerated.item[0] >> 1; + usMS = ucontrol->value.enumerated.item[0] & 1; + + /* push our values into the register - consider that things will be left + * in a funky state if the write fails */ + + usReg = snd_ac97_read(pac97, 0x7a); + snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14)); + usReg = snd_ac97_read(pac97, 0x20); + snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8)); + + return 0; +} + +static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { + + AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0), + /* + * These are used to enable/disable surround sound on motherboards + * that have 3 bidirectional analog jacks + */ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Smart 5.1 Select", + .info = snd_ac97_vt1617a_smart51_info, + .get = snd_ac97_vt1617a_smart51_get, + .put = snd_ac97_vt1617a_smart51_put, + }, +}; + int patch_vt1617a(struct snd_ac97 * ac97) { - /* bring analog power consumption to normal, like WinXP driver - * for EPIA SP + int err = 0; + + /* we choose to not fail out at this point, but we tell the + caller when we return */ + + err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0], + ARRAY_SIZE(snd_ac97_controls_vt1617a)); + + /* bring analog power consumption to normal by turning off the + * headphone amplifier, like WinXP driver for EPIA SP */ snd_ac97_write_cache(ac97, 0x5c, 0x20); ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; ac97->build_ops = &patch_vt1616_ops; - return 0; + + return err; } /* @@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = { .update_jacks = it2646_update_jacks }; -int patch_it2646(struct snd_ac97 * ac97) +static int patch_it2646(struct snd_ac97 * ac97) { ac97->build_ops = &patch_it2646_ops; /* full DAC volume */ @@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = { .build_specific = patch_si3036_specific, }; -int mpatch_si3036(struct snd_ac97 * ac97) +static int mpatch_si3036(struct snd_ac97 * ac97) { ac97->build_ops = &patch_si3036_ops; snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); @@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = { { } /* terminator */ }; -int patch_lm4550(struct snd_ac97 *ac97) +static int patch_lm4550(struct snd_ac97 *ac97) { ac97->res_table = lm4550_restbl; return 0; @@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = { .build_specific = patch_ucb1400_specific, }; -int patch_ucb1400(struct snd_ac97 * ac97) +static int patch_ucb1400(struct snd_ac97 * ac97) { ac97->build_ops = &patch_ucb1400_ops; /* enable headphone driver and smart low power mode by default */ diff --git a/trunk/sound/pci/ac97/ac97_patch.h b/trunk/sound/pci/ac97/ac97_patch.h index 555d1c9a98fd..fd341ce63762 100644 --- a/trunk/sound/pci/ac97/ac97_patch.h +++ b/trunk/sound/pci/ac97/ac97_patch.h @@ -22,44 +22,72 @@ * */ -int patch_yamaha_ymf753(struct snd_ac97 * ac97); -int patch_wolfson00(struct snd_ac97 * ac97); -int patch_wolfson03(struct snd_ac97 * ac97); -int patch_wolfson04(struct snd_ac97 * ac97); -int patch_wolfson05(struct snd_ac97 * ac97); -int patch_wolfson11(struct snd_ac97 * ac97); -int patch_wolfson13(struct snd_ac97 * ac97); -int patch_tritech_tr28028(struct snd_ac97 * ac97); -int patch_sigmatel_stac9700(struct snd_ac97 * ac97); -int patch_sigmatel_stac9708(struct snd_ac97 * ac97); -int patch_sigmatel_stac9721(struct snd_ac97 * ac97); -int patch_sigmatel_stac9744(struct snd_ac97 * ac97); -int patch_sigmatel_stac9756(struct snd_ac97 * ac97); -int patch_sigmatel_stac9758(struct snd_ac97 * ac97); -int patch_cirrus_cs4299(struct snd_ac97 * ac97); -int patch_cirrus_spdif(struct snd_ac97 * ac97); -int patch_conexant(struct snd_ac97 * ac97); -int patch_cx20551(struct snd_ac97 * ac97); -int patch_ad1819(struct snd_ac97 * ac97); -int patch_ad1881(struct snd_ac97 * ac97); -int patch_ad1885(struct snd_ac97 * ac97); -int patch_ad1886(struct snd_ac97 * ac97); -int patch_ad1888(struct snd_ac97 * ac97); -int patch_ad1980(struct snd_ac97 * ac97); -int patch_ad1981a(struct snd_ac97 * ac97); -int patch_ad1981b(struct snd_ac97 * ac97); -int patch_ad1985(struct snd_ac97 * ac97); -int patch_ad1986(struct snd_ac97 * ac97); -int patch_alc650(struct snd_ac97 * ac97); -int patch_alc655(struct snd_ac97 * ac97); -int patch_alc850(struct snd_ac97 * ac97); -int patch_cm9738(struct snd_ac97 * ac97); -int patch_cm9739(struct snd_ac97 * ac97); -int patch_cm9761(struct snd_ac97 * ac97); -int patch_cm9780(struct snd_ac97 * ac97); -int patch_vt1616(struct snd_ac97 * ac97); -int patch_vt1617a(struct snd_ac97 * ac97); -int patch_it2646(struct snd_ac97 * ac97); -int patch_ucb1400(struct snd_ac97 * ac97); -int mpatch_si3036(struct snd_ac97 * ac97); -int patch_lm4550(struct snd_ac97 * ac97); +#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \ + ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \ + ((invert) << 24)) +#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \ + (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) +#define AC97_SINGLE(xname, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } +#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } +#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } + +/* enum control */ +struct ac97_enum { + unsigned char reg; + unsigned char shift_l; + unsigned char shift_r; + unsigned short mask; + const char **texts; +}; + +#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ +{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ + .mask = xmask, .texts = xtexts } +#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ + AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) +#define AC97_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_enum_double, \ + .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ + .private_value = (unsigned long)&xenum } + +/* ac97_codec.c */ +static const struct snd_kcontrol_new snd_ac97_controls_3d[]; +static const struct snd_kcontrol_new snd_ac97_controls_spdif[]; +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97); +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix); +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix); +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix); +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst); +static void snd_ac97_restore_status(struct snd_ac97 *ac97); +static void snd_ac97_restore_iec958(struct snd_ac97 *ac97); +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); diff --git a/trunk/sound/pci/ac97/ac97_pcm.c b/trunk/sound/pci/ac97/ac97_pcm.c index 3758d07182f8..4281e6d0c5b6 100644 --- a/trunk/sound/pci/ac97/ac97_pcm.c +++ b/trunk/sound/pci/ac97/ac97_pcm.c @@ -34,7 +34,6 @@ #include #include #include -#include "ac97_patch.h" #include "ac97_id.h" #include "ac97_local.h" diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index ba7fa22b285d..e1ed59549c50 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -69,10 +69,10 @@ module_param(enable, bool, 0444); * Debug part definitions */ -//#define ALI_DEBUG +/* #define ALI_DEBUG */ #ifdef ALI_DEBUG -#define snd_ali_printk(format, args...) printk(format, ##args); +#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args); #else #define snd_ali_printk(format, args...) #endif @@ -105,10 +105,10 @@ module_param(enable, bool, 0444); * Direct Registers */ -#define ALI_LEGACY_DMAR0 0x00 // ADR0 -#define ALI_LEGACY_DMAR4 0x04 // CNT0 -#define ALI_LEGACY_DMAR11 0x0b // MOD -#define ALI_LEGACY_DMAR15 0x0f // MMR +#define ALI_LEGACY_DMAR0 0x00 /* ADR0 */ +#define ALI_LEGACY_DMAR4 0x04 /* CNT0 */ +#define ALI_LEGACY_DMAR11 0x0b /* MOD */ +#define ALI_LEGACY_DMAR15 0x0f /* MMR */ #define ALI_MPUR0 0x20 #define ALI_MPUR1 0x21 #define ALI_MPUR2 0x22 @@ -175,7 +175,7 @@ struct snd_ali; struct snd_ali_voice; struct snd_ali_channel_control { - // register data + /* register data */ struct REGDATA { unsigned int start; unsigned int stop; @@ -183,7 +183,7 @@ struct snd_ali_channel_control { unsigned int ainten; } data; - // register addresses + /* register addresses */ struct REGS { unsigned int start; unsigned int stop; @@ -197,19 +197,18 @@ struct snd_ali_channel_control { struct snd_ali_voice { unsigned int number; - unsigned int use: 1, - pcm: 1, - midi: 1, - mode: 1, - synth: 1; + unsigned int use :1, + pcm :1, + midi :1, + mode :1, + synth :1, + running :1; /* PCM data */ struct snd_ali *codec; struct snd_pcm_substream *substream; struct snd_ali_voice *extra; - unsigned int running: 1; - int eso; /* final ESO value for channel */ int count; /* runtime->period_size */ @@ -231,14 +230,12 @@ struct snd_alidev { }; -#ifdef CONFIG_PM #define ALI_GLOBAL_REGS 56 #define ALI_CHANNEL_REGS 8 struct snd_ali_image { - unsigned long regs[ALI_GLOBAL_REGS]; - unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; + u32 regs[ALI_GLOBAL_REGS]; + u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; }; -#endif struct snd_ali { @@ -246,8 +243,8 @@ struct snd_ali { unsigned long port; unsigned char revision; - unsigned int hw_initialized: 1; - unsigned int spdif_support: 1; + unsigned int hw_initialized :1; + unsigned int spdif_support :1; struct pci_dev *pci; struct pci_dev *pci_m1533; @@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids); static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); -static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short); - -/* - * Debug Part - */ - -#ifdef ALI_DEBUG - -static void ali_read_regs(struct snd_ali *codec, int channel) -{ - int i,j; - unsigned int dwVal; - - printk("channel %d registers map:\n", channel); - outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR)); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ", j*4); - printk("\n"); - - for (i=0; i<=0xf8/4;i++) { - if(i%8 == 0) - printk("%2.2x ", (i*4/0x10)*0x10); - dwVal = inl(ALI_REG(codec,i*4)); - printk("%8.8x ", dwVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} -static void ali_read_cfg(unsigned int vendor, unsigned deviceid) -{ - unsigned int dwVal; - struct pci_dev *pci_dev; - int i,j; - - pci_dev = pci_get_device(vendor, deviceid, NULL); - if (pci_dev == NULL) - return ; - - printk("\nM%x PCI CFG\n", deviceid); - printk(" "); - for(j=0;j<8;j++) - printk("%d ",j); - printk("\n"); - - for(i=0;i<8;i++) { - printk("%d ",i); - for(j=0;j<8;j++) - { - pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal); - printk("%8.8x ", dwVal); - } - printk("\n"); - } - pci_dev_put(pci_dev); - } -static void ali_read_ac97regs(struct snd_ali *codec, int secondary) -{ - unsigned short i,j; - unsigned short wVal; - - printk("\ncodec %d registers map:\n", secondary); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ",j*2); - printk("\n"); - - for (i=0; i<64;i++) { - if(i%8 == 0) - printk("%2.2x ", (i/8)*0x10); - wVal = snd_ali_codec_peek(codec, secondary, i*2); - printk("%4.4x ", wVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} - -#endif +static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, + unsigned short); /* * AC97 ACCESS */ static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, - unsigned int port ) + unsigned int port) { return (unsigned int)inl(ALI_REG(codec, port)); } -static inline void snd_ali_5451_poke( struct snd_ali *codec, - unsigned int port, - unsigned int val ) +static inline void snd_ali_5451_poke(struct snd_ali *codec, + unsigned int port, + unsigned int val) { outl((unsigned int)val, ALI_REG(codec, port)); } -static int snd_ali_codec_ready( struct snd_ali *codec, - unsigned int port ) +static int snd_ali_codec_ready(struct snd_ali *codec, + unsigned int port) { unsigned long end_time; unsigned int res; @@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec, end_time = jiffies + msecs_to_jiffies(250); do { res = snd_ali_5451_peek(codec,port); - if (! (res & 0x8000)) + if (!(res & 0x8000)) return 0; schedule_timeout_uninterruptible(1); } while (time_after_eq(end_time, jiffies)); @@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) } static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, - unsigned short reg, - unsigned short val) + unsigned short reg, + unsigned short val) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); @@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000 | (val << 16); - if (secondary) dwVal |= 0x0080; - if (codec->revision == ALI_5451_V02) dwVal |= 0x0100; + if (secondary) + dwVal |= 0x0080; + if (codec->revision == ALI_5451_V02) + dwVal |= 0x0100; - snd_ali_5451_poke(codec,port,dwVal); + snd_ali_5451_poke(codec, port, dwVal); return ; } -static unsigned short snd_ali_codec_peek( struct snd_ali *codec, - int secondary, - unsigned short reg) +static unsigned short snd_ali_codec_peek(struct snd_ali *codec, + int secondary, + unsigned short reg) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); @@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000; /* bit 15*/ - if (secondary) dwVal |= 0x0080; + if (secondary) + dwVal |= 0x0080; snd_ali_5451_poke(codec, port, dwVal); @@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, if (snd_ali_codec_ready(codec, port) < 0) return ~0; - return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16; + return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16; } static void snd_ali_codec_write(struct snd_ac97 *ac97, @@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); - if(reg == AC97_GPIO_STATUS) { - outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE, - ALI_REG(codec, ALI_AC97_GPIO)); + if (reg == AC97_GPIO_STATUS) { + outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE, + ALI_REG(codec, ALI_AC97_GPIO)); return; } snd_ali_codec_poke(codec, ac97->num, reg, val); @@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, } -static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg) +static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, + unsigned short reg) { struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_read reg=%xh.\n", reg); - return (snd_ali_codec_peek(codec, ac97->num, reg)); + return snd_ali_codec_peek(codec, ac97->num, reg); } /* @@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r static int snd_ali_reset_5451(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; unsigned short wCount, wReg; unsigned int dwVal; - if ((pci_dev = codec->pci_m1533) != NULL) { + pci_dev = codec->pci_m1533; + if (pci_dev) { pci_read_config_dword(pci_dev, 0x7c, &dwVal); pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); udelay(5000); @@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec) wCount = 200; while(wCount--) { wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec) static int snd_ali_reset_codec(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; - unsigned char bVal = 0; + struct pci_dev *pci_dev; + unsigned char bVal; unsigned int dwVal; unsigned short wCount, wReg; @@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec) udelay(15000); wCount = 200; - while(wCount--) { + while (wCount--) { wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec) * ALI 5451 Controller */ -static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_enable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal |= 1 << (channel & 0x0000001f); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal &= ~(1 << (channel & 0x0000001f)); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_enable_address_interrupt(struct snd_ali * codec) +static void snd_ali_enable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec) outl( gc, ALI_REG(codec, ALI_GC_CIR)); } -static void snd_ali_disable_address_interrupt(struct snd_ali * codec) +static void snd_ali_disable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec) outl(gc, ALI_REG(codec, ALI_GC_CIR)); } -#if 0 // not used -static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_enable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel snd_ali_printk("enable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten |= mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } #endif -static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe snd_ali_printk("disable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten &= ~mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) @@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) unsigned int idx = channel & 0x1f; if (codec->synth.chcnt >= ALI_CHANNELS){ - snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n"); + snd_printk(KERN_ERR + "ali_alloc_pcm_channel: no free channels.\n"); return -1; } @@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec) snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); - // recording + /* recording */ if (rec) { if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)) + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_IN_SUPPORT)) idx = ALI_SPDIF_IN_CHANNEL; else idx = ALI_PCM_IN_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n"); + else { + snd_printk(KERN_ERR "ali_find_free_channel: " + "record channel is busy now.\n"); return -1; } } - //playback... + /* playback... */ if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE)) { idx = ALI_SPDIF_OUT_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n"); - } + else + snd_printk(KERN_ERR "ali_find_free_channel: " + "S/PDIF out channel is in busy now.\n"); } for (idx = 0; idx < ALI_CHANNELS; idx++) { - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; } snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); @@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) return; if (!(codec->synth.chmap & (1 << idx))) { - snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel); + snd_printk(KERN_ERR "ali_free_channel_pcm: " + "channel %d is not in use.\n", channel); return; } else { codec->synth.chmap &= ~(1 << idx); @@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) } } -#if 0 // not used -static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) } #endif -static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel) +static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval) currenttimer = inl(ALI_REG(codec, ALI_STIMER)); while (currenttimer < begintimer + interval) { - if(snd_ali_stimer_ready(codec) < 0) + if (snd_ali_stimer_ready(codec) < 0) break; currenttimer = inl(ALI_REG(codec, ALI_STIMER)); + cpu_relax(); } } static void snd_ali_detect_spdif_rate(struct snd_ali *codec) { - u16 wval = 0; + u16 wval; u16 count = 0; - u8 bval = 0, R1 = 0, R2 = 0; + u8 bval, R1 = 0, R2; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); bval |= 0x1F; - outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1)); - while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) { + while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) { count ++; snd_ali_delay(codec, 6); - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); R1 = bval & 0x1F; } @@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) snd_ali_delay(codec, 6); bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); R2 = bval & 0x1F; - if (R2 != R1) R1 = R2; else break; + if (R2 != R1) + R1 = R2; + else + break; } if (count > 50000) { @@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) } if (R2 >= 0x0b && R2 <= 0x0e) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x09 << 8 | (u16)0x05; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x09 << 8) | 0x05; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3)); } else if (R2 == 0x12) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x0E << 8 | (u16)0x08; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x0e << 8) | 0x08; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3)); } } static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) { - u32 dwRate = 0; - u8 bval = 0; + u32 dwRate; + u8 bval; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); - bval &= 0x7F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); + bval &= 0x7f; bval |= 0x40; - outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL)); snd_ali_detect_spdif_rate(codec); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)); - bval &= 0x0F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)); + bval &= 0x0f; - if (bval == 0) dwRate = 44100; - if (bval == 1) dwRate = 48000; - if (bval == 2) dwRate = 32000; + switch (bval) { + case 0: dwRate = 44100; break; + case 1: dwRate = 48000; break; + case 2: dwRate = 32000; break; + default: dwRate = 0; break; + } return dwRate; } @@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec) static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) { unsigned char bVal; - unsigned int dwRate = 0; + unsigned int dwRate; - if (rate == 32000) dwRate = 0x300; - if (rate == 44100) dwRate = 0; - if (rate == 48000) dwRate = 0x200; + switch (rate) { + case 32000: dwRate = 0x300; break; + case 48000: dwRate = 0x200; break; + default: dwRate = 0; break; + } bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); bVal &= (unsigned char)(~(1<<6)); - bVal |= 0x80; //select right + bVal |= 0x80; /* select right */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); - bVal &= (~0x80); //select left + bVal &= ~0x80; /* select left */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); } @@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) { unsigned short wVal; unsigned char bVal; - - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; pci_dev = codec->pci_m1533; if (pci_dev == NULL) @@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); - { - wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); - wVal |= ALI_SPDIF_OUT_SEL_PCM; - outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); - snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); - } + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); + wVal |= ALI_SPDIF_OUT_SEL_PCM; + outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); + snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal &= ~ALI_SPDIF_OUT_SEL_PCM; @@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) wVal &= (~0x0002); outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); */ - snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); + snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal |= ALI_SPDIF_OUT_SEL_PCM; outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); @@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec) snd_ali_disable_spdif_chnout(codec); } -static void snd_ali_update_ptr(struct snd_ali *codec,int channel) +static void snd_ali_update_ptr(struct snd_ali *codec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; struct snd_pcm_runtime *runtime; - struct snd_ali_channel_control *pchregs = NULL; + struct snd_ali_channel_control *pchregs; unsigned int old, mask; #ifdef ALI_DEBUG unsigned int temp, cspf; @@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs = &(codec->chregs); - // check if interrupt occurred for channel + /* check if interrupt occurred for channel */ old = pchregs->data.aint; - mask = ((unsigned int) 1L) << (channel & 0x1f); + mask = 1U << (channel & 0x1f); if (!(old & mask)) return; @@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; #endif if (pvoice->running) { - snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf); + snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n", + (u16)temp, cspf); spin_unlock(&codec->reg_lock); snd_pcm_period_elapsed(pvoice->substream); spin_lock(&codec->reg_lock); @@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs->data.aint = old & (~mask); } -static void snd_ali_interrupt(struct snd_ali * codec) +static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) { + struct snd_ali *codec = dev_id; int channel; unsigned int audio_int; - struct snd_ali_channel_control *pchregs = NULL; - pchregs = &(codec->chregs); + struct snd_ali_channel_control *pchregs; + + if (codec == NULL || !codec->hw_initialized) + return IRQ_NONE; audio_int = inl(ALI_REG(codec, ALI_MISCINT)); + if (!audio_int) + return IRQ_NONE; + + pchregs = &(codec->chregs); if (audio_int & ADDRESS_IRQ) { - // get interrupt status for all channels - pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint)); - for (channel = 0; channel < ALI_CHANNELS; channel++) { + /* get interrupt status for all channels */ + pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint)); + for (channel = 0; channel < ALI_CHANNELS; channel++) snd_ali_update_ptr(codec, channel); - } } outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), - ALI_REG(codec,ALI_MISCINT)); -} - - -static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) -{ - struct snd_ali *codec = dev_id; + ALI_REG(codec, ALI_MISCINT)); - if (codec == NULL) - return IRQ_NONE; - snd_ali_interrupt(codec); return IRQ_HANDLED; } -static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel) +static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, + int type, int rec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; int idx; - snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec); + snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec); spin_lock_irq(&codec->voice_alloc); if (type == SNDRV_ALI_VOICE_TYPE_PCM) { idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : snd_ali_find_free_channel(codec,rec); - if(idx < 0) { + if (idx < 0) { snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); spin_unlock_irq(&codec->voice_alloc); return NULL; @@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ } -static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice) +static void snd_ali_free_voice(struct snd_ali * codec, + struct snd_ali_voice *pvoice) { void (*private_free)(void *); void *private_data; @@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo private_data = pvoice->private_data; pvoice->private_free = NULL; pvoice->private_data = NULL; - if (pvoice->pcm) { + if (pvoice->pcm) snd_ali_free_channel_pcm(codec, pvoice->number); - } pvoice->use = pvoice->pcm = pvoice->synth = 0; pvoice->substream = NULL; spin_unlock_irq(&codec->voice_alloc); @@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo } -static void snd_ali_clear_voices(struct snd_ali * codec, - unsigned int v_min, - unsigned int v_max) +static void snd_ali_clear_voices(struct snd_ali *codec, + unsigned int v_min, + unsigned int v_max) { unsigned int i; @@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec, } } -static void snd_ali_write_voice_regs(struct snd_ali * codec, +static void snd_ali_write_voice_regs(struct snd_ali *codec, unsigned int Channel, unsigned int LBA, unsigned int CSO, @@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, { unsigned int ctlcmds[4]; - outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR)); + outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR)); ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); ctlcmds[1] = LBA; @@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, outb(Channel, ALI_REG(codec, ALI_GC_CIR)); - outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS)); - outl(ctlcmds[1], ALI_REG(codec,ALI_LBA)); - outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA)); - outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC)); + outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS)); + outl(ctlcmds[1], ALI_REG(codec, ALI_LBA)); + outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA)); + outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC)); outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ @@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec) { unsigned int delta; - if (rate < 4000) rate = 4000; - if (rate > 48000) rate = 48000; + if (rate < 4000) + rate = 4000; + if (rate > 48000) + rate = 48000; if (rec) { if (rate == 44100) @@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) */ CTRL = 0x00000001; if (snd_pcm_format_width(runtime->format) == 16) - CTRL |= 0x00000008; // 16-bit data + CTRL |= 0x00000008; /* 16-bit data */ if (!snd_pcm_format_unsigned(runtime->format)) - CTRL |= 0x00000002; // signed data + CTRL |= 0x00000002; /* signed data */ if (runtime->channels > 1) - CTRL |= 0x00000004; // stereo data + CTRL |= 0x00000004; /* stereo data */ return CTRL; } @@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) * PCM part */ -static int snd_ali_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - static int snd_ali_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_ali *codec = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag; - struct snd_ali_voice *pvoice = NULL, *evoice = NULL; + struct snd_ali_voice *pvoice, *evoice; unsigned int val; int do_start; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - do_start = 1; break; + do_start = 1; + break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: - do_start = 0; break; + do_start = 0; + break; default: return -EINVAL; } what = whati = capture_flag = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { pvoice = s->runtime->private_data; evoice = pvoice->extra; what |= 1 << (pvoice->number & 0x1f); - if (evoice == NULL) { + if (evoice == NULL) whati |= 1 << (pvoice->number & 0x1f); - } else { + else { whati |= 1 << (evoice->number & 0x1f); what |= 1 << (evoice->number & 0x1f); } @@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, } } spin_lock(&codec->reg_lock); - if (! do_start) { + if (!do_start) outl(what, ALI_REG(codec, ALI_STOP)); - } val = inl(ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) val |= whati; - } else { + else val &= ~whati; - } outl(val, ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) outl(what, ALI_REG(codec, ALI_START)); - } - snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati); + snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati); spin_unlock(&codec->reg_lock); return 0; } static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice->extra; int err; - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (err < 0) return err; + + err = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + if (err < 0) + return err; /* voice management */ - if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) { - if (evoice == NULL) { - evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); - if (evoice == NULL) + if (params_buffer_size(hw_params) / 2 != + params_period_size(hw_params)) { + if (!evoice) { + evoice = snd_ali_alloc_voice(codec, + SNDRV_ALI_VOICE_TYPE_PCM, + 0, -1); + if (!evoice) return -ENOMEM; pvoice->extra = evoice; evoice->substream = substream; } } else { - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = evoice = NULL; } @@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; snd_pcm_lib_free_pages(substream); - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = NULL; } @@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) } static int snd_ali_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); } static int snd_ali_hw_free(struct snd_pcm_substream *substream) @@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set Delta (rate) value */ Delta = snd_ali_convert_rate(runtime->rate, 0); - if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || - (pvoice->number == ALI_PCM_IN_CHANNEL)) + if (pvoice->number == ALI_SPDIF_IN_CHANNEL || + pvoice->number == ALI_PCM_IN_CHANNEL) snd_ali_disable_special_channel(codec, pvoice->number); else if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) - && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE) + && pvoice->number == ALI_SPDIF_OUT_CHANNEL) { snd_ali_set_spdif_out_rate(codec, runtime->rate); Delta = 0x1000; } @@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count); + snd_ali_printk("playback_prepare: eso=%xh count=%xh\n", + pvoice->eso, pvoice->count); /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso -1; @@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) PAN = 0; VOL = 0; EC = 0; - snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); - snd_ali_write_voice_regs( codec, - pvoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - PAN, - VOL, - CTRL, - EC); - if (evoice != NULL) { + snd_ali_printk("playback_prepare:\n"); + snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n", + pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); + snd_ali_write_voice_regs(codec, + pvoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + PAN, + VOL, + CTRL, + EC); + if (!evoice) { evoice->count = pvoice->count; evoice->eso = pvoice->count << 1; ESO = evoice->eso - 1; snd_ali_write_voice_regs(codec, - evoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - (unsigned int)0x7f, - (unsigned int)0x3ff, - CTRL, - EC); + evoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + 0x7f, + 0x3ff, + CTRL, + EC); } spin_unlock_irq(&codec->reg_lock); return 0; @@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); - // Prepare capture intr channel + /* Prepare capture intr channel */ if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { unsigned int rate; @@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) rate = snd_ali_get_spdif_in_rate(codec); if (rate == 0) { - snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n"); + snd_printk(KERN_WARNING "ali_capture_preapre: " + "spdif rate detect err!\n"); rate = 48000; } spin_lock_irq(&codec->reg_lock); @@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) } if (rate != 48000) - Delta = ((rate << 12)/runtime->rate)&0x00ffff; + Delta = ((rate << 12) / runtime->rate) & 0x00ffff; } - // set target ESO for channel + /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - // set interrupt count size + /* set interrupt count size */ pvoice->count = runtime->period_size; - // set Loop Back Address + /* set Loop Back Address */ LBA = runtime->dma_addr; - // set ESO to capture first MIDLP interrupt + /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso - 1; CTRL = snd_ali_control_mode(substream); GVSEL = 0; @@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) CTRL, EC); - spin_unlock_irq(&codec->reg_lock); return 0; } -static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t +snd_ali_playback_pointer(struct snd_pcm_substream *substream) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; @@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) static struct snd_pcm_hardware snd_ali_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback = static struct snd_pcm_hardware snd_ali_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) } } -static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel, - struct snd_pcm_hardware *phw) +static int snd_ali_open(struct snd_pcm_substream *substream, int rec, + int channel, struct snd_pcm_hardware *phw) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice; - pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel); - if (pvoice == NULL) + pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, + channel); + if (!pvoice) return -EAGAIN; pvoice->substream = substream; @@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe runtime->hw = *phw; snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, + 0, 64*1024); return 0; } @@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) static struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_playback_hw_params, .hw_free = snd_ali_playback_hw_free, .prepare = snd_ali_playback_prepare, @@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { static struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_hw_params, .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, @@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, { struct snd_ali *chip = snd_pcm_substream_chip(substream); unsigned int modem_num = chip->num_of_codecs - 1; - snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); + snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, + params_rate(hw_params)); snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); return snd_ali_hw_params(substream, hw_params); } static struct snd_pcm_hardware snd_ali_modem = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000), .rate_min = 8000, .rate_max = 16000, .channels_min = 1, @@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem = .fifo_size = 0, }; -static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel) +static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, + int channel) { - static unsigned int rates [] = {8000,9600,12000,16000}; + static unsigned int rates[] = {8000, 9600, 12000, 16000}; static struct snd_pcm_hw_constraint_list hw_constraint_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, }; int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); + if (err) return err; return snd_pcm_hw_constraint_list(substream->runtime, 0, @@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm) } -static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc) +static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, + struct ali_pcm_description *desc) { struct snd_pcm *pcm; int err; @@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ pcm->private_data = codec; pcm->private_free = snd_ali_pcm_free; if (desc->playback_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + desc->playback_ops); if (desc->capture_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + desc->capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(codec->pci), 64*1024, 128*1024); + snd_dma_pci_data(codec->pci), + 64*1024, 128*1024); pcm->info_flags = 0; pcm->dev_class = desc->class; @@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ } static struct ali_pcm_description ali_pcms[] = { - { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, - { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM } + { .name = "ALI 5451", + .playback_num = ALI_CHANNELS, + .capture_num = 1, + .playback_ops = &snd_ali_playback_ops, + .capture_ops = &snd_ali_capture_ops + }, + { .name = "ALI 5451 modem", + .playback_num = 1, + .capture_num = 1, + .playback_ops = &snd_ali_modem_playback_ops, + .capture_ops = &snd_ali_modem_capture_ops, + .class = SNDRV_PCM_CLASS_MODEM + } }; static int __devinit snd_ali_build_pcms(struct snd_ali *codec) { int i, err; - for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++) - if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0) + for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) { + err = snd_ali_pcm(codec, i, &ali_pcms[i]); + if (err < 0) return err; + } return 0; } @@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ .put = snd_ali5451_spdif_put, .private_value = value} -static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int enable; @@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e enable = ucontrol->value.integer.value[0] ? 1 : 0; spin_lock_irq(&codec->reg_lock); - switch(kcontrol->private_value) { + switch (kcontrol->private_value) { case 0: enable = (codec->spdif_mask & 0x02) ? 1 : 0; break; case 1: - enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0; + enable = ((codec->spdif_mask & 0x02) && + (codec->spdif_mask & 0x04)) ? 1 : 0; break; case 2: enable = (codec->spdif_mask & 0x01) ? 1 : 0; @@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int change = 0, enable = 0; @@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = { ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) }; -static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus) -{ - struct snd_ali *codec = bus->private_data; - codec->ac97_bus = NULL; -} - -static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97) -{ - struct snd_ali *codec = ac97->private_data; - codec->ac97[ac97->num] = NULL; -} - static int __devinit snd_ali_mixer(struct snd_ali * codec) { struct snd_ac97_template ac97; @@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) .read = snd_ali_codec_read, }; - if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0) + err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus); + if (err < 0) return err; - codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = codec; - ac97.private_free = snd_ali_mixer_free_ac97; - for ( i = 0 ; i < codec->num_of_codecs ; i++) { + for (i = 0; i < codec->num_of_codecs; i++) { ac97.num = i; - if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { - snd_printk(KERN_ERR "ali mixer %d creating error.\n", i); - if(i == 0) + err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]); + if (err < 0) { + snd_printk(KERN_ERR + "ali mixer %d creating error.\n", i); + if (i == 0) return err; codec->num_of_codecs = 1; break; @@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) } if (codec->spdif_support) { - for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { - err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); - if (err < 0) return err; + for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { + err = snd_ctl_add(codec->card, + snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); + if (err < 0) + return err; } } return 0; @@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) int i, j; im = chip->image; - if (! im) + if (!im) return 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for(i = 0 ; i < chip->num_of_codecs ; i++) { + for (i = 0; i < chip->num_of_codecs; i++) { snd_pcm_suspend_all(chip->pcm[i]); snd_ac97_suspend(chip->ac97[i]); } @@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) spin_lock_irq(&chip->reg_lock); im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); - // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); + /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); - // disable all IRQ bits + /* disable all IRQ bits */ outl(0, ALI_REG(chip, ALI_MISCINT)); for (i = 0; i < ALI_GLOBAL_REGS; i++) { @@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); } - // stop all HW channel + /* stop all HW channel */ outl(0xffffffff, ALI_REG(chip, ALI_STOP)); spin_unlock_irq(&chip->reg_lock); @@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci) int i, j; im = chip->image; - if (! im) + if (!im) return 0; pci_set_power_state(pci, PCI_D0); @@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci) } for (i = 0; i < ALI_GLOBAL_REGS; i++) { - if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START)) + if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || + (i*4 == ALI_START)) continue; outl(im->regs[i], ALI_REG(chip, i*4)); } - // start HW channel + /* start HW channel */ outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); - // restore IRQ enable bits + /* restore IRQ enable bits */ outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); spin_unlock_irq(&chip->reg_lock); - for(i = 0 ; i < chip->num_of_codecs ; i++) + for (i = 0 ; i < chip->num_of_codecs; i++) snd_ac97_resume(chip->ac97[i]); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec) { unsigned int legacy; unsigned char temp; - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; snd_ali_printk("chip initializing ... \n"); @@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec) outb(0x10, ALI_REG(codec, ALI_MPUR2)); codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); - codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS); + codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, + AC97_EXTENDED_STATUS); if (codec->spdif_support) { snd_ali_enable_spdif_out(codec); codec->spdif_mask = 0x00000002; @@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec) if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { codec->num_of_codecs++; outl(inl(ALI_REG(codec, ALI_SCTRL)) | - (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN), - ALI_REG(codec, ALI_SCTRL)); + (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 | + ALI_SCTRL_LINE_OUT_EN), + ALI_REG(codec, ALI_SCTRL)); } snd_ali_printk("chip initialize succeed.\n"); @@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec) } /* proc for register dump */ -static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) +static void snd_ali_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buf) { struct snd_ali *codec = entry->private_data; int i; - for(i = 0 ; i < 256 ; i+= 4) + for (i = 0; i < 256 ; i+= 4) snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); } static void __devinit snd_ali_proc_init(struct snd_ali *codec) { struct snd_info_entry *entry; - if(!snd_card_proc_new(codec->card, "ali5451", &entry)) + if (!snd_card_proc_new(codec->card, "ali5451", &entry)) snd_info_set_text_ops(entry, codec, snd_ali_proc_read); } @@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) int err; snd_ali_printk("resouces allocation ...\n"); - if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0) + err = pci_request_regions(codec->pci, "ALI 5451"); + if (err < 0) return err; codec->port = pci_resource_start(codec->pci, 0); @@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) snd_ali_printk("resouces allocated.\n"); return 0; } -static int snd_ali_dev_free(struct snd_device *device) +static int snd_ali_dev_free(struct snd_device *device) { - struct snd_ali *codec=device->device_data; + struct snd_ali *codec = device->device_data; snd_ali_free(codec); return 0; } @@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_ali_printk("creating ...\n"); /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 31 bits */ if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { - snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); + snd_printk(KERN_ERR "architecture does not support " + "31bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; } - if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { + codec = kzalloc(sizeof(*codec), GFP_KERNEL); + if (!codec) { pci_disable_device(pci); return -ENOMEM; } @@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card, /* M1533: southbridge */ codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); - if (! codec->pci_m1533) { + if (!codec->pci_m1533) { snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); snd_ali_free(codec); return -ENODEV; } /* M7101: power management */ codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); - if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { + if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); snd_ali_free(codec); return -ENODEV; } snd_ali_printk("snd_device_new is called.\n"); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); + if (err < 0) { snd_ali_free(codec); return err; } @@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); /* initialise synth voices*/ - for (i = 0; i < ALI_CHANNELS; i++ ) { + for (i = 0; i < ALI_CHANNELS; i++) codec->synth.voices[i].number = i; - } - if ((err = snd_ali_chip_init(codec)) < 0) { + err = snd_ali_chip_init(codec); + if (err < 0) { snd_printk(KERN_ERR "ali create: chip init error.\n"); return err; } #ifdef CONFIG_PM codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); - if (! codec->image) + if (!codec->image) snd_printk(KERN_WARNING "can't allocate apm buffer\n"); #endif @@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, snd_ali_printk("probe ...\n"); card = snd_card_new(index, id, THIS_MODULE, 0); - if (card == NULL) + if (!card) return -ENOMEM; - if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); + if (err < 0) + goto error; card->private_data = codec; snd_ali_printk("mixer building ...\n"); - if ((err = snd_ali_mixer(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_mixer(codec); + if (err < 0) + goto error; snd_ali_printk("pcm building ...\n"); - if ((err = snd_ali_build_pcms(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_build_pcms(codec); + if (err < 0) + goto error; snd_ali_proc_init(codec); @@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, card->shortname, codec->port, codec->irq); snd_ali_printk("register card.\n"); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto error; + pci_set_drvdata(pci, card); return 0; + + error: + snd_card_free(card); + return err; } static void __devexit snd_ali_remove(struct pci_dev *pci) diff --git a/trunk/sound/pci/au88x0/au88x0_sb.h b/trunk/sound/pci/au88x0/au88x0_sb.h deleted file mode 100644 index 5a4d8fc2bbfc..000000000000 --- a/trunk/sound/pci/au88x0/au88x0_sb.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * au88x0_sb.h - * - * Wed Oct 29 22:10:42 2003 - * - ****************************************************************************/ - -#ifdef CHIP_AU8820 -/* AU8820 starting @ 64KiB offset */ -#define SBEMU_BASE 0x10000 -#else -/* AU8810? and AU8830 starting @ 164KiB offset */ -#define SBEMU_BASE 0x29000 -#endif - -#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */ -#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */ -#define FM_A_DATA (SBEMU_BASE + 0x04) -#define FM_B_STATUS (SBEMU_BASE + 0x08) -#define FM_B_ADDRESS (SBEMU_BASE + 0x08) -#define FM_B_DATA (SBEMU_BASE + 0x0C) -#define SB_MIXER_ADDR (SBEMU_BASE + 0x10) -#define SB_MIXER_DATA (SBEMU_BASE + 0x14) -#define SB_RESET (SBEMU_BASE + 0x18) -#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C) -#define FM_STATUS2 (SBEMU_BASE + 0x20) -#define FM_ADDR2 (SBEMU_BASE + 0x20) -#define FM_DATA2 (SBEMU_BASE + 0x24) -#define SB_DSP_READ (SBEMU_BASE + 0x28) -#define SB_DSP_WRITE (SBEMU_BASE + 0x30) -#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */ -#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */ -#define SB_LACR (SBEMU_BASE + 0x40) /* ? */ -#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */ -#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */ -#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */ -#define SB_VERSION (SBEMU_BASE + 0x50) -#define SB_CTRLSTAT (SBEMU_BASE + 0x54) -#define SB_TIMERSTAT (SBEMU_BASE + 0x58) -#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */ diff --git a/trunk/sound/pci/azt3328.c b/trunk/sound/pci/azt3328.c index 43edd2839b5a..36d3666a5b77 100644 --- a/trunk/sound/pci/azt3328.c +++ b/trunk/sound/pci/azt3328.c @@ -1,6 +1,6 @@ /* * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). - * Copyright (C) 2002, 2005 by Andreas Mohr + * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr * * Framework borrowed from Bart Hartgers's als4000.c. * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), @@ -52,6 +52,9 @@ * - full duplex 16bit playback/record at independent sampling rate * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? * - game port (legacy address support) + * - builtin 3D enhancement (said to be YAMAHA Ymersion) + * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven + * features supported) * - built-in General DirectX timer having a 20 bits counter * with 1us resolution (see below!) * - I2S serial port for external DAC @@ -94,6 +97,10 @@ * * BUGS * - full-duplex might *still* be problematic, not fully tested recently + * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated + * if you set PCM output switch to "pre 3D" instead of "post 3D". + * If this can't be set, then get a mixer application that Isn't Stupid (tm) + * (e.g. kmix, gamix) - unfortunately several are!! * * TODO * - test MPU401 MIDI playback etc. @@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol, return (nreg != oreg); } -static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), @@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8), AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9), - AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ + AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), @@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata #endif }; -static const u16 __devinitdata snd_azf3328_init_values[][2] = { +static u16 __devinitdata snd_azf3328_init_values[][2] = { { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_BASSTREBLE, 0x0000 }, @@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream) struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); snd_azf3328_dbgcallenter(); - chip->playback_substream = NULL; snd_azf3328_dbgcallleave(); return 0; @@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit) } #endif +#if DEBUG_MISC static void snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) { -#if DEBUG_MISC u16 tmp; snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); @@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) for (tmp=0; tmp <= 0x01; tmp += 1) snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); - for (tmp = 0; tmp <= 0x6E; tmp += 2) - snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp)); -#endif + for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) + snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); + + for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) + snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); } +#else +static inline void +snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {} +#endif static int __devinit snd_azf3328_create(struct snd_card *card, @@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) #ifdef MODULE printk( -"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n" -"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n" +"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n" +"azt3328: Hardware was completely undocumented, unfortunately.\n" "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", 1024000 / seqtimer_scaling, seqtimer_scaling); diff --git a/trunk/sound/pci/azt3328.h b/trunk/sound/pci/azt3328.h index b4f3e3cd006b..679fa992e2bc 100644 --- a/trunk/sound/pci/azt3328.h +++ b/trunk/sound/pci/azt3328.h @@ -106,8 +106,8 @@ #define IRQ_RECORDING 0x0002 #define IRQ_MPU401 0x0010 #define IRQ_TIMER 0x0020 /* DirectX timer */ - #define IRQ_UNKNOWN1 0x0040 /* probably unused */ - #define IRQ_UNKNOWN2 0x0080 /* probably unused */ + #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ + #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ diff --git a/trunk/sound/pci/bt87x.c b/trunk/sound/pci/bt87x.c index e9b029e1cd6d..6523ba07db96 100644 --- a/trunk/sound/pci/bt87x.c +++ b/trunk/sound/pci/bt87x.c @@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), /* Viewcast Osprey 200 */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + /* ATI TV-Wonder */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), /* Leadtek Winfast tv 2000xp delux */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), /* Voodoo TV 200 */ @@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) pci->device, pci->subsystem_vendor, pci->subsystem_device); snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " - "\n"); + "\n"); return 32000; /* default rate */ } diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index ea6712b63c9f..48f3f17c5170 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_ca0106_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 extended = 0; @@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, running=0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = epcm->channel_id; diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index 2ae539b195fd..bef1f6d1859c 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); - snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); + snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n"); return -EIO; #endif diff --git a/trunk/sound/pci/cs46xx/imgs/cwcemb80.h b/trunk/sound/pci/cs46xx/imgs/cwcemb80.h deleted file mode 100644 index a64c6ff9983a..000000000000 --- a/trunk/sound/pci/cs46xx/imgs/cwcemb80.h +++ /dev/null @@ -1,1607 +0,0 @@ -/* generated from cwcemb80.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcemb80_H__ -#define __HEADER_cwcemb80_H__ - -static struct dsp_symbol_entry cwcemb80_symbols[] = { - { 0x0000, "BEGINADDRESS",0x00 }, - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0070, "SPOSCB",0x02 }, - { 0x0105, "TASKTREETHREAD",0x03 }, - { 0x0136, "TASKTREEHEADERCODE",0x03 }, - { 0x013f, "FGTASKTREEHEADERCODE",0x03 }, - { 0x0163, "NULLALGORITHM",0x03 }, - { 0x0167, "HFGEXECCHILD",0x03 }, - { 0x0168, "HFGEXECCHILD_98",0x03 }, - { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 }, - { 0x016d, "HFGEXECSIBLING",0x03 }, - { 0x016f, "HFGEXECSIBLING_298",0x03 }, - { 0x0170, "HFGEXECSIBLING_2IND1",0x03 }, - { 0x0173, "S16_CODECOUTPUTTASK",0x03 }, - { 0x018e, "#CODE_END",0x00 }, -}; /* cwcemb80 symbols */ - -static u32 cwcemb80_code[] = { -/* BEGINADDRESS */ -/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003, -/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003, -/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003, -/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003, -/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003, -/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003, -/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003, -/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003, -/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003, -/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040, -/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003, -/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003, -/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003, -/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003, -/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003, -/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003, -/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003, -/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002, -/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003, -/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000, -/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000, -/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000, -/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000, -/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003, -/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003, -/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, -/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003, -/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000, -/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000, -/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000, -/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140, -/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40, -/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00, -/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004, -/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000, -/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640, -/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0, -/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0, -/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b, -/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44, -/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917, -/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880, -/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000, -/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000, -/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40, -/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0, -/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0, -/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0, -/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0, -/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0, -/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240, -/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240, -/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240, -/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80, -/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0, -/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80, -/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0, -/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300, -/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40, -/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40, -/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0, -/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1, -/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1, -/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000, -/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0, -/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700, -/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0, -/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80, -/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500, -/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0, -/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800, -/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500, -/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0, -/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00, -/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500, -/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0, -/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80, -/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500, -/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1, -/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380, -/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000, -/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000, -/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0, -/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40, -/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0, -/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44, -/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080, -/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540, -/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0, -/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40, -/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00, -/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784, -/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240, -/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000, -/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000, -/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c, -/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, -/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000, -/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000, -/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003, -/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392, -/* 0104 */ 0x0000ba01,0x00000000, -/* TASKTREETHREAD */ -/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4, -/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001, -/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000, -/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa, -/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002, -/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000, -/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40, -/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008, -/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640, -/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0, -/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000, -/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009, -/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000, -/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000, -/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000, -/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008, -/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000, -/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000, -/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000, -/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000, -/* 0135 */ 0x00000000,0x00000000, -/* TASKTREEHEADERCODE */ -/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b, -/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b, -/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000, -/* 013E */ 0x00042731,0x00001003, -/* FGTASKTREEHEADERCODE */ -/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a, -/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b, -/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140, -/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003, -/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003, -/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003, -/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140, -/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000, -/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00, -/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000, -/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997, -/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7, -/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004, -/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000, -/* NULLALGORITHM */ -/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000, -/* HFGEXECCHILD */ -/* 0167 */ 0x00000000,0x000eba44, -/* HFGEXECCHILD_98 */ -/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0, -/* HFGEXECCHILD_PUSH1IND */ -/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 016C */ 0x00006a88,0x000c75c4, -/* HFGEXECSIBLING */ -/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44, -/* HFGEXECSIBLING_298 */ -/* 016F */ 0x00087401,0x000e4782, -/* HFGEXECSIBLING_2IND1 */ -/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 0172 */ 0x00006a88,0x000c75c4, -/* S16_CODECOUTPUTTASK */ -/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40, -/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80, -/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0, -/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0, -/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c, -/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2, -/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b, -/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916, -/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000, -/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b, -/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956, -/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40, -/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00, -/* 018D */ 0x00048f05,0x00000000 -}; -/* #CODE_END */ - -static u32 cwcemb80_parameter[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000, -/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000, -/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000, -/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2, -/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000, -/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3, -/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d, -/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000, -/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a, -/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3, -/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000, -/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2, -/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff, -/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0, -/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000, -/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9, -/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff, -/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780, -/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000, -/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9, -/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1, -/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000, -/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000, -/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004, -/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610, -/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d, -/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75, -/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051, -/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d, -/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136, -/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000, -/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d, -/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a, -/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000 -}; /* #PARAMETER_END */ - -static u32 cwcemb80_sample[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004 -}; /* #SAMPLE_END */ - - -static struct dsp_segment_desc cwcemb80_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code }, - { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter }, - { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample }, -}; - -static struct dsp_module_desc cwcemb80_module = { - "cwcemb80", - { - 38, - cwcemb80_symbols - }, - 3, - cwcemb80_segments, -}; - -#endif /* __HEADER_cwcemb80_H__ */ diff --git a/trunk/sound/pci/echoaudio/darla20.c b/trunk/sound/pci/echoaudio/darla20.c index 8e7fe033270f..87078d3a6854 100644 --- a/trunk/sound/pci/echoaudio/darla20.c +++ b/trunk/sound/pci/echoaudio/darla20.c @@ -56,6 +56,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla20_dsp.fw"); + #define FW_DARLA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/trunk/sound/pci/echoaudio/darla24.c b/trunk/sound/pci/echoaudio/darla24.c index a13c623eb999..42b48f9d2128 100644 --- a/trunk/sound/pci/echoaudio/darla24.c +++ b/trunk/sound/pci/echoaudio/darla24.c @@ -60,6 +60,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla24_dsp.fw"); + #define FW_DARLA24_DSP 0 static const struct firmware card_fw[] = { diff --git a/trunk/sound/pci/echoaudio/echo3g.c b/trunk/sound/pci/echoaudio/echo3g.c index 8fb15823aca5..8dbb7ac865c1 100644 --- a/trunk/sound/pci/echoaudio/echo3g.c +++ b/trunk/sound/pci/echoaudio/echo3g.c @@ -68,6 +68,10 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/echo3g_dsp.fw"); +MODULE_FIRMWARE("ea/3g_asic.fw"); + #define FW_361_LOADER 0 #define FW_ECHO3G_DSP 1 #define FW_3G_ASIC 2 diff --git a/trunk/sound/pci/echoaudio/echoaudio.c b/trunk/sound/pci/echoaudio/echoaudio.c index e413da00759b..f27b6a733b96 100644 --- a/trunk/sound/pci/echoaudio/echoaudio.c +++ b/trunk/sound/pci/echoaudio/echoaudio.c @@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct audiopipe *pipe = runtime->private_data; int i, err; u32 channelmask = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { for (i = 0; i < DSP_MAXPIPES; i++) { if (s == chip->substream[i]) { channelmask |= 1 << i; diff --git a/trunk/sound/pci/echoaudio/echoaudio_3g.c b/trunk/sound/pci/echoaudio/echoaudio_3g.c index 9f439ea459f4..52a933189576 100644 --- a/trunk/sound/pci/echoaudio/echoaudio_3g.c +++ b/trunk/sound/pci/echoaudio/echoaudio_3g.c @@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip) chip->asic_code = &card_fw[FW_3G_ASIC]; - /* Now give the new ASIC a little time to set up */ - mdelay(2); + /* Now give the new ASIC some time to set up */ + msleep(1000); /* See if it worked */ box_type = check_asic_status(chip); diff --git a/trunk/sound/pci/echoaudio/gina20.c b/trunk/sound/pci/echoaudio/gina20.c index af4d32026e4a..fee2d4831732 100644 --- a/trunk/sound/pci/echoaudio/gina20.c +++ b/trunk/sound/pci/echoaudio/gina20.c @@ -60,6 +60,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/gina20_dsp.fw"); + #define FW_GINA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/trunk/sound/pci/echoaudio/gina24.c b/trunk/sound/pci/echoaudio/gina24.c index 9ff454a947ed..d5eae470fe9a 100644 --- a/trunk/sound/pci/echoaudio/gina24.c +++ b/trunk/sound/pci/echoaudio/gina24.c @@ -66,6 +66,12 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_361_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_asic.fw"); +MODULE_FIRMWARE("ea/gina24_361_asic.fw"); + #define FW_361_LOADER 0 #define FW_GINA24_301_DSP 1 #define FW_GINA24_361_DSP 2 diff --git a/trunk/sound/pci/echoaudio/indigo.c b/trunk/sound/pci/echoaudio/indigo.c index 37eb726fd03d..40f601cd016f 100644 --- a/trunk/sound/pci/echoaudio/indigo.c +++ b/trunk/sound/pci/echoaudio/indigo.c @@ -58,6 +58,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DSP 1 diff --git a/trunk/sound/pci/echoaudio/indigodj.c b/trunk/sound/pci/echoaudio/indigodj.c index dc8b91824181..771c5383210d 100644 --- a/trunk/sound/pci/echoaudio/indigodj.c +++ b/trunk/sound/pci/echoaudio/indigodj.c @@ -58,6 +58,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dj_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DJ_DSP 1 diff --git a/trunk/sound/pci/echoaudio/indigoio.c b/trunk/sound/pci/echoaudio/indigoio.c index eadf3263453a..49c550defcf9 100644 --- a/trunk/sound/pci/echoaudio/indigoio.c +++ b/trunk/sound/pci/echoaudio/indigoio.c @@ -59,6 +59,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_io_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_IO_DSP 1 diff --git a/trunk/sound/pci/echoaudio/layla20.c b/trunk/sound/pci/echoaudio/layla20.c index 6cede497579e..8f5483a405ae 100644 --- a/trunk/sound/pci/echoaudio/layla20.c +++ b/trunk/sound/pci/echoaudio/layla20.c @@ -66,6 +66,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/layla20_dsp.fw"); +MODULE_FIRMWARE("ea/layla20_asic.fw"); + #define FW_LAYLA20_DSP 0 #define FW_LAYLA20_ASIC 1 diff --git a/trunk/sound/pci/echoaudio/layla24.c b/trunk/sound/pci/echoaudio/layla24.c index 44f735426aa0..0524667c02f7 100644 --- a/trunk/sound/pci/echoaudio/layla24.c +++ b/trunk/sound/pci/echoaudio/layla24.c @@ -68,6 +68,12 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_1_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2A_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2S_asic.fw"); + #define FW_361_LOADER 0 #define FW_LAYLA24_DSP 1 #define FW_LAYLA24_1_ASIC 2 diff --git a/trunk/sound/pci/echoaudio/mia.c b/trunk/sound/pci/echoaudio/mia.c index dc172d03ac3f..893c7c20dd70 100644 --- a/trunk/sound/pci/echoaudio/mia.c +++ b/trunk/sound/pci/echoaudio/mia.c @@ -66,6 +66,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mia_dsp.fw"); + #define FW_361_LOADER 0 #define FW_MIA_DSP 1 diff --git a/trunk/sound/pci/echoaudio/mona.c b/trunk/sound/pci/echoaudio/mona.c index c856ed50dd9a..3a5d5b0020df 100644 --- a/trunk/sound/pci/echoaudio/mona.c +++ b/trunk/sound/pci/echoaudio/mona.c @@ -64,6 +64,15 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_dsp.fw"); +MODULE_FIRMWARE("ea/mona_361_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_2_asic.fw"); + #define FW_361_LOADER 0 #define FW_MONA_301_DSP 1 #define FW_MONA_361_DSP 2 diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 80aa585eade4..dbc805c33fc4 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -49,6 +49,13 @@ #include "p17v.h" +#define HANA_FILENAME "emu/hana.fw" +#define DOCK_FILENAME "emu/audio_dock.fw" + +MODULE_FIRMWARE(HANA_FILENAME); +MODULE_FIRMWARE(DOCK_FILENAME); + + /************************************************************************* * EMU10K1 init / done *************************************************************************/ @@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) int tmp,tmp2; int reg; int err; - const char *hana_filename = "emu/hana.fw"; - const char *dock_filename = "emu/audio_dock.fw"; snd_printk(KERN_INFO "emu1010: Special config.\n"); /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, @@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename); + if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { + snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); return err; } @@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) { + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { return err; } snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); @@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spi_dac = 1, .i2c_adc = 1, .spk71 = 1} , + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, + .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", + .id = "EMU1010", + .emu10k2_chip = 1, + .ca0108_chip = 1, + .ca_cardbus_chip = 1, + .spi_dac = 1, + .i2c_adc = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", diff --git a/trunk/sound/pci/emu10k1/p16v.c b/trunk/sound/pci/emu10k1/p16v.c index 465f8d505329..7ee19c63c2c8 100644 --- a/trunk/sound/pci/emu10k1/p16v.c +++ b/trunk/sound/pci/emu10k1/p16v.c @@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_emu10k1_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 inte = 0; @@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, running = 0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = substream->pcm->device-emu->p16v_device_offset; diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 425b167522d5..6a0ddcf00884 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_P1_PAUSE; snd_pcm_trigger_done(s, substream); @@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_DAC1_EN; snd_pcm_trigger_done(s, substream); diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index dc84c189b05f..2faf009076bb 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); @@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); diff --git a/trunk/sound/pci/hda/Makefile b/trunk/sound/pci/hda/Makefile index 60d7b05a204a..b2484bbdcc1d 100644 --- a/trunk/sound/pci/hda/Makefile +++ b/trunk/sound/pci/hda/Makefile @@ -1,5 +1,8 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o \ +# since snd-hda-intel is the only driver using hda-codec, +# merge it into a single module although it was originally +# designed to be individual modules +snd-hda-intel-objs += hda_codec.o \ hda_generic.o \ patch_realtek.o \ patch_cmedia.o \ @@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \ patch_conexant.o \ patch_via.o ifdef CONFIG_PROC_FS -snd-hda-codec-objs += hda_proc.o +snd-hda-intel-objs += hda_proc.o endif -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o +obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 8f34fb447983..14649d54b493 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include "hda_codec.h" @@ -34,11 +33,6 @@ #include "hda_local.h" -MODULE_AUTHOR("Takashi Iwai "); -MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec"); -MODULE_LICENSE("GPL"); - - /* * vendor / preset table */ @@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = { * * Returns the obtained response value, or -1 for an error. */ -unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, +unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm) { unsigned int res; mutex_lock(&codec->bus->cmd_mutex); - if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) + if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) res = codec->bus->ops.get_response(codec); else res = (unsigned int)-1; @@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire return res; } -EXPORT_SYMBOL(snd_hda_codec_read); - /** * snd_hda_codec_write - send a single command without waiting for response * @codec: the HDA codec @@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, return err; } -EXPORT_SYMBOL(snd_hda_codec_write); - /** * snd_hda_sequence_write - sequence writes * @codec: the HDA codec @@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); } -EXPORT_SYMBOL(snd_hda_sequence_write); - /** * snd_hda_get_sub_nodes - get the range of sub nodes * @codec: the HDA codec @@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write); * Parse the NID and store the start NID of its sub-nodes. * Returns the number of sub-nodes. */ -int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id) +int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *start_id) { unsigned int parm; @@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta return (int)(parm & 0x7fff); } -EXPORT_SYMBOL(snd_hda_get_sub_nodes); - /** * snd_hda_get_connections - get connection list * @codec: the HDA codec @@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, conn_len = parm & AC_CLIST_LENGTH; mask = (1 << (shift-1)) - 1; - if (! conn_len) + if (!conn_len) return 0; /* no connection */ if (conn_len == 1) { /* single connection */ - parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0); + parm = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_LIST, 0); conn_list[0] = parm & mask; return 1; } @@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, if (i % num_elems == 0) parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i); - range_val = !! (parm & (1 << (shift-1))); /* ranges */ + range_val = !!(parm & (1 << (shift-1))); /* ranges */ val = parm & mask; parm >>= shift; if (range_val) { /* ranges between the previous and this one */ - if (! prev_nid || prev_nid >= val) { - snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); + if (!prev_nid || prev_nid >= val) { + snd_printk(KERN_WARNING "hda_codec: " + "invalid dep_range_val %x:%x\n", + prev_nid, val); continue; } for (n = prev_nid + 1; n <= val; n++) { if (conns >= max_conns) { - snd_printk(KERN_ERR "Too many connections\n"); + snd_printk(KERN_ERR + "Too many connections\n"); return -EINVAL; } conn_list[conns++] = n; @@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) struct hda_bus_unsolicited *unsol; unsigned int wp; - if ((unsol = bus->unsol) == NULL) + unsol = bus->unsol; + if (!unsol) return 0; wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; @@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) return 0; } -EXPORT_SYMBOL(snd_hda_queue_unsol_event); - /* * process queueud unsolicited events */ @@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work) rp <<= 1; res = unsol->queue[rp]; caddr = unsol->queue[rp + 1]; - if (! (caddr & (1 << 4))) /* no unsolicited event? */ + if (!(caddr & (1 << 4))) /* no unsolicited event? */ continue; codec = bus->caddr_tbl[caddr & 0x0f]; if (codec && codec->patch_ops.unsol_event) @@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work) /* * initialize unsolicited queue */ -static int init_unsol_queue(struct hda_bus *bus) +static int __devinit init_unsol_queue(struct hda_bus *bus) { struct hda_bus_unsolicited *unsol; @@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus) return 0; unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); - if (! unsol) { - snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); + if (!unsol) { + snd_printk(KERN_ERR "hda_codec: " + "can't allocate unsolicited queue\n"); return -ENOMEM; } INIT_WORK(&unsol->work, process_unsol_events); @@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec); static int snd_hda_bus_free(struct hda_bus *bus) { - struct list_head *p, *n; + struct hda_codec *codec, *n; - if (! bus) + if (!bus) return 0; if (bus->unsol) { flush_scheduled_work(); kfree(bus->unsol); } - list_for_each_safe(p, n, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry_safe(codec, n, &bus->codec_list, list) { snd_hda_codec_free(codec); } if (bus->ops.private_free) @@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device) * * Returns 0 if successful, or a negative error code. */ -int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, - struct hda_bus **busp) +int __devinit snd_hda_bus_new(struct snd_card *card, + const struct hda_bus_template *temp, + struct hda_bus **busp) { struct hda_bus *bus; int err; @@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, mutex_init(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); - if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); + if (err < 0) { snd_hda_bus_free(bus); return err; } @@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, return 0; } -EXPORT_SYMBOL(snd_hda_bus_new); - /* * find a matching codec preset */ -static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) +static const struct hda_codec_preset __devinit * +find_codec_preset(struct hda_codec *codec) { const struct hda_codec_preset **tbl, *preset; + if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) + return NULL; /* use the generic parser */ + for (tbl = hda_preset_tables; *tbl; tbl++) { for (preset = *tbl; preset->id; preset++) { u32 mask = preset->mask; - if (! mask) + if (!mask) mask = ~0; if (preset->id == (codec->vendor_id & mask) && - (! preset->rev || + (!preset->rev || preset->rev == codec->revision_id)) return preset; } @@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec, break; } } - if (! vendor) { + if (!vendor) { sprintf(tmp, "Generic %04x", vendor_id); vendor = tmp; } if (codec->preset && codec->preset->name) snprintf(name, namelen, "%s %s", vendor, codec->preset->name); else - snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff); + snprintf(name, namelen, "%s ID %x", vendor, + codec->vendor_id & 0xffff); } /* * look for an AFG and MFG nodes */ -static void setup_fg_nodes(struct hda_codec *codec) +static void __devinit setup_fg_nodes(struct hda_codec *codec) { int i, total_nodes; hda_nid_t nid; total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); for (i = 0; i < total_nodes; i++, nid++) { - switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { + unsigned int func; + func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE); + switch (func & 0xff) { case AC_GRP_AUDIO_FUNCTION: codec->afg = nid; break; @@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, &codec->start_nid); codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); - if (! codec->wcaps) + if (!codec->wcaps) return -ENOMEM; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) @@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) */ static void snd_hda_codec_free(struct hda_codec *codec) { - if (! codec) + if (!codec) return; list_del(&codec->list); codec->bus->caddr_tbl[codec->addr] = NULL; @@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec); * * Returns 0 if successful, or a negative error code. */ -int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, - struct hda_codec **codecp) +int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, + struct hda_codec **codecp) { struct hda_codec *codec; char component[13]; @@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); if (bus->caddr_tbl[codec_addr]) { - snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr); + snd_printk(KERN_ERR "hda_codec: " + "address 0x%x is already occupied\n", codec_addr); return -EBUSY; } @@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; - codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); + codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_VENDOR_ID); if (codec->vendor_id == -1) /* read again, hopefully the access method was corrected * in the last read... */ codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); - codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); - codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); + codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_SUBSYSTEM_ID); + codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_REV_ID); setup_fg_nodes(codec); - if (! codec->afg && ! codec->mfg) { + if (!codec->afg && !codec->mfg) { snd_printdd("hda_codec: no AFG or MFG node found\n"); snd_hda_codec_free(codec); return -ENODEV; @@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return -ENOMEM; } - if (! codec->subsystem_id) { + if (!codec->subsystem_id) { hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; - codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_SUBSYSTEM_ID, - 0); + codec->subsystem_id = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_SUBSYSTEM_ID, 0); } codec->preset = find_codec_preset(codec); - if (! *bus->card->mixername) + /* audio codec should override the mixer name */ + if (codec->afg || !*bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); @@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return 0; } -EXPORT_SYMBOL(snd_hda_codec_new); - /** * snd_hda_codec_setup_stream - set up the codec for streaming * @codec: the CODEC to set up @@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new); * @channel_id: channel id to pass, zero based. * @format: stream format. */ -void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, +void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, + u32 stream_tag, int channel_id, int format) { - if (! nid) + if (!nid) return; - snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", + snd_printdd("hda_codec_setup_stream: " + "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", nid, stream_tag, channel_id, format); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | channel_id); @@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); } -EXPORT_SYMBOL(snd_hda_codec_setup_stream); - /* * amp access functions */ @@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream); #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) /* initialize the hash table */ -static void init_amp_hash(struct hda_codec *codec) +static void __devinit init_amp_hash(struct hda_codec *codec) { memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); codec->num_amp_entries = 0; @@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) if (codec->num_amp_entries >= codec->amp_info_size) { /* reallocate the array */ int new_size = codec->amp_info_size + 64; - struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info), - GFP_KERNEL); - if (! new_info) { - snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n"); + struct hda_amp_info *new_info; + new_info = kcalloc(new_size, sizeof(struct hda_amp_info), + GFP_KERNEL); + if (!new_info) { + snd_printk(KERN_ERR "hda_codec: " + "can't malloc amp_info\n"); return NULL; } if (codec->amp_info) { memcpy(new_info, codec->amp_info, - codec->amp_info_size * sizeof(struct hda_amp_info)); + codec->amp_info_size * + sizeof(struct hda_amp_info)); kfree(codec->amp_info); } codec->amp_info_size = new_size; @@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) */ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + if (!info) return 0; - if (! (info->status & INFO_AMP_CAPS)) { - if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) + if (!(info->status & INFO_AMP_CAPS)) { + if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) nid = codec->afg; - info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? - AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); + info->amp_caps = snd_hda_param_read(codec, nid, + direction == HDA_OUTPUT ? + AC_PAR_AMP_OUT_CAP : + AC_PAR_AMP_IN_CAP); info->status |= INFO_AMP_CAPS; } return info->amp_caps; @@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) * read the current volume to info * if the cache exists, read the cache value. */ -static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index) +static unsigned int get_vol_mute(struct hda_codec *codec, + struct hda_amp_info *info, hda_nid_t nid, + int ch, int direction, int index) { u32 val, parm; @@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; parm |= index; - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, parm); info->vol[ch] = val & 0xff; info->status |= INFO_AMP_VOL(ch); return info->vol[ch]; @@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i * write the current volume in info to the h/w and update the cache */ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index, int val) + hda_nid_t nid, int ch, int direction, int index, + int val) { u32 parm; @@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); - if (! info) + struct hda_amp_info *info; + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); + if (!info) return 0; return get_vol_mute(codec, info, nid, ch, direction, index); } @@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + if (!info) return 0; val &= mask; val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; - if (info->vol[ch] == val && ! codec->in_resume) + if (info->vol[ch] == val && !codec->in_resume) return 0; put_vol_mute(codec, info, nid, ch, direction, idx, val); return 1; @@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) /* volume */ -int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); u16 nid = get_amp_nid(kcontrol); @@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ u32 caps; caps = query_amp_caps(codec, nid, dir); - caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */ - if (! caps) { - printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid); + /* num steps */ + caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; + if (!caps) { + printk(KERN_WARNING "hda_codec: " + "num_steps = 0 for NID=0x%x\n", nid); return -EINVAL; } uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, if (size < 4 * sizeof(unsigned int)) return -ENOMEM; caps = query_amp_caps(codec, nid, dir); - val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25; + val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; + val2 = (val2 + 1) * 25; val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); val1 = ((int)val1) * ((int)val2); if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) @@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, } /* switch */ -int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int chs = get_amp_channels(kcontrol); @@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e long *valp = ucontrol->value.integer.value; if (chs & 1) - *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1; + *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & + 0x80) ? 0 : 1; if (chs & 2) - *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1; + *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & + 0x80) ? 0 : 1; return 0; } -int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e #define AMP_VAL_IDX_SHIFT 19 #define AMP_VAL_IDX_MASK (0x0f<<19) -int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ return err; } -int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { - kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); + kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | + (i << AMP_VAL_IDX_SHIFT); err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); if (err < 0) break; @@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ * SPDIF out controls */ -static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0; } -static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits) unsigned short val = 0; if (sbits & IEC958_AES0_PROFESSIONAL) - val |= 1 << 6; + val |= AC_DIG1_PROFESSIONAL; if (sbits & IEC958_AES0_NONAUDIO) - val |= 1 << 5; + val |= AC_DIG1_NONAUDIO; if (sbits & IEC958_AES0_PROFESSIONAL) { - if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015) - val |= 1 << 3; + if ((sbits & IEC958_AES0_PRO_EMPHASIS) == + IEC958_AES0_PRO_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; } else { - if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015) - val |= 1 << 3; - if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) - val |= 1 << 4; + if ((sbits & IEC958_AES0_CON_EMPHASIS) == + IEC958_AES0_CON_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; + if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) + val |= AC_DIG1_COPYRIGHT; if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) - val |= 1 << 7; + val |= AC_DIG1_LEVEL; val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); } return val; @@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val) { unsigned int sbits = 0; - if (val & (1 << 5)) + if (val & AC_DIG1_NONAUDIO) sbits |= IEC958_AES0_NONAUDIO; - if (val & (1 << 6)) + if (val & AC_DIG1_PROFESSIONAL) sbits |= IEC958_AES0_PROFESSIONAL; if (sbits & IEC958_AES0_PROFESSIONAL) { - if (sbits & (1 << 3)) + if (sbits & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_PRO_EMPHASIS_5015; } else { - if (val & (1 << 3)) + if (val & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_CON_EMPHASIS_5015; - if (! (val & (1 << 4))) + if (!(val & AC_DIG1_COPYRIGHT)) sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; - if (val & (1 << 7)) + if (val & AC_DIG1_LEVEL) sbits |= (IEC958_AES1_CON_ORIGINAL << 8); sbits |= val & (0x7f << 8); } return sbits; } -static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c codec->spdif_ctls = val; if (change || codec->in_resume) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, + val >> 8); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s return 0; } -static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = codec->spdif_ctls & 1; + ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; return 0; } -static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn int change; mutex_lock(&codec->spdif_mutex); - val = codec->spdif_ctls & ~1; + val = codec->spdif_ctls & ~AC_DIG1_ENABLE; if (ucontrol->value.integer.value[0]) - val |= 1; + val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; if (change || codec->in_resume) { codec->spdif_ctls = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | - AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + /* unmute amp switch (if any) */ + if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && + (val & AC_DIG1_ENABLE)) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | + AC_AMP_SET_OUTPUT); } mutex_unlock(&codec->spdif_mutex); return change; @@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); + codec->spdif_ctls = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); return 0; } @@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) #define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info -static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd return 0; } -static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd change = codec->spdif_in_enable != val; if (change || codec->in_resume) { codec->spdif_in_enable = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1; + codec->spdif_in_enable = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & + AC_DIG1_ENABLE; return 0; } @@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, * * Returns 0 if successful, otherwise a negative error code. */ -int snd_hda_build_controls(struct hda_bus *bus) +int __devinit snd_hda_build_controls(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; /* build controls */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; - if (! codec->patch_ops.build_controls) + if (!codec->patch_ops.build_controls) continue; err = codec->patch_ops.build_controls(codec); if (err < 0) @@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus) } /* initialize */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); - if (! codec->patch_ops.init) + if (!codec->patch_ops.init) continue; err = codec->patch_ops.init(codec); if (err < 0) @@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_controls); - /* * stream formats */ @@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = { { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ +#define AC_PAR_PCM_RATE_BITS 11 + /* up to bits 10, 384kHZ isn't supported properly */ + + /* not autodetected value */ + { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ { 0 } /* terminator */ }; @@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val = rate_bits[i].hda_fmt; break; } - if (! rate_bits[i].hz) { + if (!rate_bits[i].hz) { snd_printdd("invalid rate %d\n", rate); return 0; } @@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val |= 0x20; break; default: - snd_printdd("invalid format width %d\n", snd_pcm_format_width(format)); + snd_printdd("invalid format width %d\n", + snd_pcm_format_width(format)); return 0; } return val; } -EXPORT_SYMBOL(snd_hda_calc_stream_format); - /** * snd_hda_query_supported_pcm - query the supported PCM rates and formats * @codec: the HDA codec @@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return -EIO; } - if (! val) + if (!val) val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (ratesp) { u32 rates = 0; - for (i = 0; rate_bits[i].hz; i++) { + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } @@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (streams == -1) return -EIO; - if (! streams) { - streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); + if (!streams) { + streams = snd_hda_param_read(codec, codec->afg, + AC_PAR_STREAM); if (streams == -1) return -EIO; } @@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 24; else if (val & AC_SUPPCM_BITS_20) bps = 20; - } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) { + } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24| + AC_SUPPCM_BITS_32)) { formats |= SNDRV_PCM_FMTBIT_S32_LE; if (val & AC_SUPPCM_BITS_32) bps = 32; @@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 20; } } - else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ + else if (streams == AC_SUPFMT_FLOAT32) { + /* should be exclusive */ formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; bps = 32; - } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ + } else if (streams == AC_SUPFMT_AC3) { + /* should be exclusive */ /* temporary hack: we have still no proper support * for the direct AC3 stream... */ @@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, } /** - * snd_hda_is_supported_format - check whether the given node supports the format val + * snd_hda_is_supported_format - check whether the given node supports + * the format val * * Returns 1 if supported, 0 if not. */ @@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return 0; } - if (! val) { + if (!val) { val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (val == -1) return 0; } rate = format & 0xff00; - for (i = 0; rate_bits[i].hz; i++) + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) if (rate_bits[i].hda_fmt == rate) { if (val & (1 << i)) break; return 0; } - if (! rate_bits[i].hz) + if (i >= AC_PAR_PCM_RATE_BITS) return 0; stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (stream == -1) return 0; - if (! stream && nid != codec->afg) + if (!stream && nid != codec->afg) stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); - if (! stream || stream == -1) + if (!stream || stream == -1) return 0; if (stream & AC_SUPFMT_PCM) { switch (format & 0xf0) { case 0x00: - if (! (val & AC_SUPPCM_BITS_8)) + if (!(val & AC_SUPPCM_BITS_8)) return 0; break; case 0x10: - if (! (val & AC_SUPPCM_BITS_16)) + if (!(val & AC_SUPPCM_BITS_16)) return 0; break; case 0x20: - if (! (val & AC_SUPPCM_BITS_20)) + if (!(val & AC_SUPPCM_BITS_20)) return 0; break; case 0x30: - if (! (val & AC_SUPPCM_BITS_24)) + if (!(val & AC_SUPPCM_BITS_24)) return 0; break; case 0x40: - if (! (val & AC_SUPPCM_BITS_32)) + if (!(val & AC_SUPPCM_BITS_32)) return 0; break; default: @@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info) +static int __devinit set_pcm_default_values(struct hda_codec *codec, + struct hda_pcm_stream *info) { - if (info->nid) { - /* query support PCM information from the given NID */ - if (! info->rates || ! info->formats) - snd_hda_query_supported_pcm(codec, info->nid, - info->rates ? NULL : &info->rates, - info->formats ? NULL : &info->formats, - info->maxbps ? NULL : &info->maxbps); + /* query support PCM information from the given NID */ + if (info->nid && (!info->rates || !info->formats)) { + snd_hda_query_supported_pcm(codec, info->nid, + info->rates ? NULL : &info->rates, + info->formats ? NULL : &info->formats, + info->maxbps ? NULL : &info->maxbps); } if (info->ops.open == NULL) info->ops.open = hda_pcm_default_open_close; @@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream * * This function returns 0 if successfull, or a negative error code. */ -int snd_hda_build_pcms(struct hda_bus *bus) +int __devinit snd_hda_build_pcms(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { unsigned int pcm, s; int err; - if (! codec->patch_ops.build_pcms) + if (!codec->patch_ops.build_pcms) continue; err = codec->patch_ops.build_pcms(codec); if (err < 0) @@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus) for (s = 0; s < 2; s++) { struct hda_pcm_stream *info; info = &codec->pcm_info[pcm].stream[s]; - if (! info->substreams) + if (!info->substreams) continue; err = set_pcm_default_values(codec, info); if (err < 0) @@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_pcms); - /** * snd_hda_check_board_config - compare the current codec with the config table * @codec: the HDA codec @@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms); * * If no entries are matching, the function returns a negative value. */ -int snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char **models, - const struct snd_pci_quirk *tbl) +int __devinit snd_hda_check_board_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) { if (codec->bus->modelname && models) { int i; @@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec, * * Returns 0 if successful, or a negative error code. */ -int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, + struct snd_kcontrol_new *knew) { int err; for (; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; err = snd_ctl_add(codec->bus->card, kctl); if (err < 0) { - if (! codec->addr) + if (!codec->addr) return err; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; kctl->id.device = codec->addr; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } } @@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) /* * Channel mode helper */ -int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, - const struct hda_channel_mode *chmode, int num_chmodes) +int snd_hda_ch_mode_info(struct hda_codec *codec, + struct snd_ctl_elem_info *uinfo, + const struct hda_channel_mode *chmode, + int num_chmodes) { uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf return 0; } -int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_get(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int max_channels) { int i; @@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon return 0; } -int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_put(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int *max_channelsp) { unsigned int mode; mode = ucontrol->value.enumerated.item[0]; snd_assert(mode < num_chmodes, return -EINVAL); - if (*max_channelsp == chmode[mode].channels && ! codec->in_resume) + if (*max_channelsp == chmode[mode].channels && !codec->in_resume) return 0; /* change the current channel setting */ *max_channelsp = chmode[mode].channels; @@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon /* * input MUX helper */ -int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) +int snd_hda_input_mux_info(const struct hda_input_mux *imux, + struct snd_ctl_elem_info *uinfo) { unsigned int index; @@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem return 0; } -int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, - struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, +int snd_hda_input_mux_put(struct hda_codec *codec, + const struct hda_input_mux *imux, + struct snd_ctl_elem_value *ucontrol, + hda_nid_t nid, unsigned int *cur_val) { unsigned int idx; @@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); @@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i * Multi-channel / digital-out PCM helper functions */ +/* setup SPDIF output stream */ +static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, + unsigned int stream_tag, unsigned int format) +{ + /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); + /* turn on again (if needed) */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & 0xff); +} + /* * open the digital out in the exclusive mode */ -int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_open(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); - if (mout->dig_out_used) { - mutex_unlock(&codec->spdif_mutex); - return -EBUSY; /* already being used */ - } + if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) + /* already opened as analog dup; reset it once */ + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); mout->dig_out_used = HDA_DIG_EXCLUSIVE; mutex_unlock(&codec->spdif_mutex); return 0; } +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + mutex_lock(&codec->spdif_mutex); + setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); + mutex_unlock(&codec->spdif_mutex); + return 0; +} + /* * release the digital out */ -int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_close(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); mout->dig_out_used = 0; @@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m /* * set up more restrictions for analog out */ -int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_open(struct hda_codec *codec, + struct hda_multi_out *mout, struct snd_pcm_substream *substream) { substream->runtime->hw.channels_max = mout->max_channels; @@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out * set up the i/o for analog out * when the digital out is available, copy the front out to digital out, too. */ -int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) @@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o mutex_lock(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { if (chs == 2 && - snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && - ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { + snd_hda_is_supported_format(codec, mout->dig_out_nid, + format) && + !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { mout->dig_out_used = HDA_DIG_ANALOG_DUP; - /* setup digital receiver */ - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, - stream_tag, 0, format); + setup_dig_out_stream(codec, mout->dig_out_nid, + stream_tag, format); } else { mout->dig_out_used = 0; - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, + 0, 0, 0); } } mutex_unlock(&codec->spdif_mutex); /* front */ - snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, + 0, format); if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]) /* headphone out will just decode front left/right (stereo) */ - snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, + 0, format); /* extra outputs copied from front */ for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) if (mout->extra_out_nid[i]) @@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* surrounds */ for (i = 1; i < mout->num_dacs; i++) { if (chs >= (i + 1) * 2) /* independent out */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + i * 2, format); else /* copy front */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + 0, format); } return 0; } @@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* * clean up the setting for analog out */ -int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout) { hda_nid_t *nids = mout->dac_nids; int i; @@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o * Helper for automatic ping configuration */ -static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) +static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) { for (; *list; list++) if (*list == nid) @@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) return 0; } + +/* + * Sort an associated group of pins according to their sequence numbers. + */ +static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, + int num_pins) +{ + int i, j; + short seq; + hda_nid_t nid; + + for (i = 0; i < num_pins; i++) { + for (j = i + 1; j < num_pins; j++) { + if (sequences[i] > sequences[j]) { + seq = sequences[i]; + sequences[i] = sequences[j]; + sequences[j] = seq; + nid = pins[i]; + pins[i] = pins[j]; + pins[j] = nid; + } + } + } +} + + /* * Parse all pin widgets and store the useful pin nids to cfg * @@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, * respectively. */ -int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids) +int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, + struct auto_pin_cfg *cfg, + hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; - int i, j, nodes; - short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; + int nodes; + short seq, assoc_line_out, assoc_speaker; + short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; + short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; memset(cfg, 0, sizeof(*cfg)); - memset(sequences, 0, sizeof(sequences)); - assoc_line_out = 0; + memset(sequences_line_out, 0, sizeof(sequences_line_out)); + memset(sequences_speaker, 0, sizeof(sequences_speaker)); + assoc_line_out = assoc_speaker = 0; nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); for (nid = nid_start; nid < nodes + nid_start; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); - unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; unsigned int def_conf; short assoc, loc; @@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c if (ignore_nids && is_in_nid_list(nid, ignore_nids)) continue; - def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) continue; loc = get_defcfg_location(def_conf); @@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c case AC_JACK_LINE_OUT: seq = get_defcfg_sequence(def_conf); assoc = get_defcfg_association(def_conf); - if (! assoc) + if (!assoc) continue; - if (! assoc_line_out) + if (!assoc_line_out) assoc_line_out = assoc; else if (assoc_line_out != assoc) continue; if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) continue; cfg->line_out_pins[cfg->line_outs] = nid; - sequences[cfg->line_outs] = seq; + sequences_line_out[cfg->line_outs] = seq; cfg->line_outs++; break; case AC_JACK_SPEAKER: + seq = get_defcfg_sequence(def_conf); + assoc = get_defcfg_association(def_conf); + if (! assoc) + continue; + if (! assoc_speaker) + assoc_speaker = assoc; + else if (assoc_speaker != assoc) + continue; if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) continue; cfg->speaker_pins[cfg->speaker_outs] = nid; + sequences_speaker[cfg->speaker_outs] = seq; cfg->speaker_outs++; break; case AC_JACK_HP_OUT: @@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c } /* sort by sequence */ - for (i = 0; i < cfg->line_outs; i++) - for (j = i + 1; j < cfg->line_outs; j++) - if (sequences[i] > sequences[j]) { - seq = sequences[i]; - sequences[i] = sequences[j]; - sequences[j] = seq; - nid = cfg->line_out_pins[i]; - cfg->line_out_pins[i] = cfg->line_out_pins[j]; - cfg->line_out_pins[j] = nid; - } + sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, + cfg->line_outs); + sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, + cfg->speaker_outs); + + /* + * FIX-UP: if no line-outs are detected, try to use speaker or HP pin + * as a primary output + */ + if (!cfg->line_outs) { + if (cfg->speaker_outs) { + cfg->line_outs = cfg->speaker_outs; + memcpy(cfg->line_out_pins, cfg->speaker_pins, + sizeof(cfg->speaker_pins)); + cfg->speaker_outs = 0; + memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); + cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; + } else if (cfg->hp_outs) { + cfg->line_outs = cfg->hp_outs; + memcpy(cfg->line_out_pins, cfg->hp_pins, + sizeof(cfg->hp_pins)); + cfg->hp_outs = 0; + memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); + cfg->line_out_type = AUTO_PIN_HP_OUT; + } + } /* Reorder the surround channels * ALSA sequence is front/surr/clfe/side * HDA sequence is: * 4-ch: front/surr => OK as it is * 6-ch: front/clfe/surr - * 8-ch: front/clfe/side/surr + * 8-ch: front/clfe/rear/side|fc */ switch (cfg->line_outs) { case 3: - nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[2]; - cfg->line_out_pins[2] = nid; - break; case 4: nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[3]; - cfg->line_out_pins[3] = cfg->line_out_pins[2]; + cfg->line_out_pins[1] = cfg->line_out_pins[2]; cfg->line_out_pins[2] = nid; break; } @@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c cfg->input_pins[AUTO_PIN_CD], cfg->input_pins[AUTO_PIN_AUX]); - /* - * FIX-UP: if no line-outs are detected, try to use speaker or HP pin - * as a primary output - */ - if (! cfg->line_outs) { - if (cfg->speaker_outs) { - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - } else if (cfg->hp_outs) { - cfg->line_outs = cfg->hp_outs; - memcpy(cfg->line_out_pins, cfg->hp_pins, - sizeof(cfg->hp_pins)); - cfg->hp_outs = 0; - memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); - } - } - return 0; } @@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { */ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) { - struct list_head *p; + struct hda_codec *codec; /* FIXME: should handle power widget capabilities */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec, state); hda_set_power_state(codec, @@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) return 0; } -EXPORT_SYMBOL(snd_hda_suspend); - /** * snd_hda_resume - resume the codecs * @bus: the HDA bus @@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend); */ int snd_hda_resume(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); @@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_resume); - /** * snd_hda_resume_ctls - resume controls in the new control list * @codec: the HDA codec @@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) struct snd_ctl_elem_value *val; val = kmalloc(sizeof(*val), GFP_KERNEL); - if (! val) + if (!val) return -ENOMEM; codec->in_resume = 1; for (; knew->name; knew++) { @@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec) return snd_hda_resume_ctls(codec, dig_in_ctls); } #endif - -/* - * INIT part - */ - -static int __init alsa_hda_init(void) -{ - return 0; -} - -static void __exit alsa_hda_exit(void) -{ -} - -module_init(alsa_hda_init) -module_exit(alsa_hda_exit) diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index c12bc4e8840f..56c26e7ccdf1 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -233,7 +233,7 @@ enum { */ /* Amp gain/mute */ -#define AC_AMP_MUTE (1<<8) +#define AC_AMP_MUTE (1<<7) #define AC_AMP_GAIN (0x7f) #define AC_AMP_GET_INDEX (0xf<<0) diff --git a/trunk/sound/pci/hda/hda_generic.c b/trunk/sound/pci/hda/hda_generic.c index 1e5ff0cd3709..000287f7da43 100644 --- a/trunk/sound/pci/hda/hda_generic.c +++ b/trunk/sound/pci/hda/hda_generic.c @@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid return -ENOMEM; } } - memcpy(node->conn_list, conn_list, nconns); + memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); node->nconns = nconns; node->wid_caps = get_wcaps(codec, nid); node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 1672cace1ae7..2fa281cbef91 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{ATI, SB600}," "{ATI, RS600}," "{ATI, RS690}," + "{ATI, RS780}," + "{ATI, R600}," "{VIA, VT8251}," "{VIA, VT8237A}," "{SiS, SIS966}," @@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define RIRB_INT_MASK 0x05 /* STATESTS int mask: SD2,SD1,SD0 */ +#define AZX_MAX_CODECS 3 #define STATESTS_INT_MASK 0x07 /* SD_CTL bits */ @@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { static int __devinit azx_codec_create(struct azx *chip, const char *model) { struct hda_bus_template bus_temp; - int c, codecs, err; + int c, codecs, audio_codecs, err; memset(&bus_temp, 0, sizeof(bus_temp)); bus_temp.private_data = chip; @@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) return err; - codecs = 0; - for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) { + codecs = audio_codecs = 0; + for (c = 0; c < AZX_MAX_CODECS; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { - err = snd_hda_codec_new(chip->bus, c, NULL); + struct hda_codec *codec; + err = snd_hda_codec_new(chip->bus, c, &codec); if (err < 0) continue; codecs++; + if (codec->afg) + audio_codecs++; } } - if (! codecs) { + if (!audio_codecs) { + /* probe additional slots if no codec is found */ + for (; c < azx_max_codecs[chip->driver_type]; c++) { + if ((chip->codec_mask & (1 << c)) & probe_mask) { + err = snd_hda_codec_new(chip->bus, c, NULL); + if (err < 0) + continue; + codecs++; + } + } + } + if (!codecs) { snd_printk(KERN_ERR SFX "no codecs initialized\n"); return -ENXIO; } @@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device) /* * white/black-listing for position_fix */ -static const struct snd_pci_quirk position_fix_list[] __devinitdata = { +static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), {} }; @@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = { { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ + { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */ + { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 39718d6cdadd..be12b8814c39 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -148,6 +148,11 @@ struct hda_multi_out { int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, @@ -217,6 +222,12 @@ enum { AUTO_PIN_LAST }; +enum { + AUTO_PIN_LINE_OUT, + AUTO_PIN_SPEAKER_OUT, + AUTO_PIN_HP_OUT +}; + extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { @@ -225,6 +236,7 @@ struct auto_pin_cfg { int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; + int line_out_type; /* AUTO_PIN_XXX_OUT */ hda_nid_t hp_pins[5]; hda_nid_t input_pins[AUTO_PIN_LAST]; hda_nid_t dig_out_pin; diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index f94f1f22889e..0e1a879663fa 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = ad198x_dig_playback_pcm_open, - .close = ad198x_dig_playback_pcm_close + .close = ad198x_dig_playback_pcm_close, + .prepare = ad198x_dig_playback_pcm_prepare }, }; @@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = { { } /* end */ }; -/* additional verbs for 3-stack model */ -static struct hda_verb ad1986a_3st_init_verbs[] = { - /* Mic and line-in selectors */ - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, - {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, - { } /* end */ -}; - static struct hda_verb ad1986a_ch2_init[] = { /* Surround out -> Line In */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + /* Line-in selectors */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch4_init[] = { /* Surround out -> Surround */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch6_init[] = { /* Surround out -> Surround out */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> CLFE */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, { } /* end */ }; @@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), @@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec) case AD1986A_3STACK: spec->num_mixers = 2; spec->mixers[1] = ad1986a_3st_mixers; - spec->num_init_verbs = 3; - spec->init_verbs[1] = ad1986a_3st_init_verbs; - spec->init_verbs[2] = ad1986a_ch2_init; + spec->num_init_verbs = 2; + spec->init_verbs[1] = ad1986a_ch2_init; spec->channel_mode = ad1986a_modes; spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); spec->need_dac_fix = 1; @@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); if (sel > 0) { - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (sel <= 3) + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0); + if (sel < 3) sel++; else sel = 0; @@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int sel; + unsigned int val, sel; int change; + val = ucontrol->value.enumerated.item[0]; sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (! ucontrol->value.enumerated.item[0]) { + if (!val) { change = sel != 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 0); } else { change = sel == 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1); - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; - change |= sel == ucontrol->value.enumerated.item[0]; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, - ucontrol->value.enumerated.item[0] - 1); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 1); + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0) + 1; + change |= sel != val; + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x0b, 0, + AC_VERB_SET_CONNECT_SEL, val - 1); } return change; } diff --git a/trunk/sound/pci/hda/patch_atihdmi.c b/trunk/sound/pci/hda/patch_atihdmi.c index 831469d3a923..f8eb4c90f801 100644 --- a/trunk/sound/pci/hda/patch_atihdmi.c +++ b/trunk/sound/pci/hda/patch_atihdmi.c @@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct atihdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .substreams = 1, .channels_min = 2, @@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .nid = 0x2, /* NID to query formats and rates and setup streams */ .ops = { .open = atihdmi_dig_playback_pcm_open, - .close = atihdmi_dig_playback_pcm_close + .close = atihdmi_dig_playback_pcm_close, + .prepare = atihdmi_dig_playback_pcm_prepare }, }; @@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_cmedia.c b/trunk/sound/pci/hda/patch_cmedia.c index 5b9d3a31a1ae..3c722e667bc8 100644 --- a/trunk/sound/pci/hda/patch_cmedia.c +++ b/trunk/sound/pci/hda/patch_cmedia.c @@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct cmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { /* NID is set in cmi9880_build_pcms */ .ops = { .open = cmi9880_dig_playback_pcm_open, - .close = cmi9880_dig_playback_pcm_close + .close = cmi9880_dig_playback_pcm_close, + .prepare = cmi9880_dig_playback_pcm_prepare }, }; diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 46e93c6b9a42..a5a4b2bddf20 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct conexant_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, + format, substream); +} + /* * Analog capture */ @@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = conexant_dig_playback_pcm_open, - .close = conexant_dig_playback_pcm_close + .close = conexant_dig_playback_pcm_close, + .prepare = conexant_dig_playback_pcm_prepare }, }; @@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, .put = conexant_ch_mode_put, \ .private_value = nid | (dir<<16) } -static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, - 0x00); - unsigned int old_data = gpio_data; - - /* Set/unset the masked GPIO bit(s) as needed */ - if (val == 0) - gpio_data &= ~mask; - else - gpio_data |= mask; - if (gpio_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); - return 1; -} - -#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_gpio_data_info, \ - .get = cxt_gpio_data_get, \ - .put = cxt_gpio_data_put, \ - .private_value = nid | (mask<<16) } -#if 0 -static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, - 0x00); - unsigned int old_data = ctrl_data; - - /* Set/unset the masked control bit(s) as needed */ - if (val == 0) - ctrl_data &= ~mask; - else - ctrl_data |= mask; - if (ctrl_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - ctrl_data); - return 1; -} - -#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_spdif_ctrl_info, \ - .get = cxt_spdif_ctrl_get, \ - .put = cxt_spdif_ctrl_put, \ - .private_value = nid | (mask<<16) } -#endif #endif /* CONFIG_SND_DEBUG */ /* Conexant 5045 specific */ @@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = spec->cur_eapd ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); @@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, return change; } +/* toggle input of built-in and mic jack appropriately */ +static void cxt5045_hp_automic(struct hda_codec *codec) +{ + static struct hda_verb mic_jack_on[] = { + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + static struct hda_verb mic_jack_off[] = { + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x12, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) + snd_hda_sequence_write(codec, mic_jack_on); + else + snd_hda_sequence_write(codec, mic_jack_off); +} + /* mute internal speaker if HP is plugged */ static void cxt5045_hp_automute(struct hda_codec *codec) @@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; + bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); } @@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, case CONEXANT_HP_EVENT: cxt5045_hp_automute(codec); break; + case CONEXANT_MIC_EVENT: + cxt5045_hp_automic(codec); + break; + } } @@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put }, - HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", @@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { static struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* HP, Amp */ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, @@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, /* Record selector: Int mic */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x0}, + {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* SPDIF route: PCM */ { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, - /* pin sensing on HP and Mic jacks */ - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* EAPD */ {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ { } /* end */ }; + +static struct hda_verb cxt5045_hp_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + { } /* end */ +}; + +static struct hda_verb cxt5045_mic_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, + { } /* end */ +}; + #ifdef CONFIG_SND_DEBUG /* Test configuration for debugging, modelled after the ALC260 test * configuration. @@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), /* Modes for retasking pin widgets */ CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), @@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), /* Loopback mixer controls */ - HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), - - HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT), + + HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - { } /* end */ }; static struct hda_verb cxt5045_test_init_verbs[] = { + /* Set connections */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable retasking pins as output, initially without power amp */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Disable digital (SPDIF) pins initially, but users can enable * them via a mixer switch. In the case of SPDIF-out, this initverb @@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = { * pin) */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Mute all inputs to mixer widget (even unconnected ones) */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ @@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec) enum { - CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_FUJITSU, /* Laptops w/ EAPD support */ #ifdef CONFIG_SND_DEBUG CXT5045_TEST, #endif @@ -836,6 +778,7 @@ enum { static const char *cxt5045_models[CXT5045_MODELS] = { [CXT5045_LAPTOP] = "laptop", + [CXT5045_FUJITSU] = "fujitsu", #ifdef CONFIG_SND_DEBUG [CXT5045_TEST] = "test", #endif @@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = { static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), - SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), + SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} }; @@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops = conexant_patch_ops; - codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, cxt5045_models, cxt5045_cfg_tbl); switch (board_config) { case CXT5045_LAPTOP: + codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; + spec->input_mux = &cxt5045_capture_source; + spec->num_init_verbs = 2; + spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; + spec->mixers[0] = cxt5045_mixers; + codec->patch_ops.init = cxt5045_init; + break; + case CXT5045_FUJITSU: spec->input_mux = &cxt5045_capture_source; spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5045_init_verbs; + spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; spec->mixers[0] = cxt5045_mixers; codec->patch_ops.init = cxt5045_init; break; @@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = { }; static struct hda_input_mux cxt5047_capture_source = { - .num_items = 2, + .num_items = 1, .items = { - { "ExtMic", 0x0 }, - { "IntMic", 0x1 }, + { "Mic", 0x2 }, } }; @@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec) }; unsigned int present; - present = snd_hda_codec_read(codec, 0x08, 0, + present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; if (present) snd_hda_sequence_write(codec, mic_jack_on); @@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5047_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = conexant_mux_enum_info, - .get = conexant_mux_enum_get, - .put = conexant_mux_enum_put - }, HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = cxt5047_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = cxt_eapd_info, - .get = cxt_eapd_get, - .put = cxt5047_hp_master_sw_put, - .private_value = 0x13, - }, + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT), {} }; @@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, - /* HP, Amp, Speaker */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {0x1A, AC_VERB_SET_CONNECT_SEL,0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, + /* HP, Speaker */ + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, + {0x13, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, - /* Record selector: Front mic */ + /* Record selector: Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, + {0x1A, AC_VERB_SET_CONNECT_SEL,0x02}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, /* SPDIF route: PCM */ { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable unsolicited events */ @@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, /* Speaker routing */ {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, - /* Change default to ExtMic for recording */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x2}, {} }; @@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = { {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, - {0x1a, AC_VERB_SET_CONNECT_SEL,0x02}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* Speaker routing */ @@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - /* Controls for GPIO pins, assuming they exist and are configured - * as outputs - */ - CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), - CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), - CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), - CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), - { } /* end */ }; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index fba3cb11bc2a..a4ede27af021 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -74,6 +74,8 @@ enum { ALC260_HP_3013, ALC260_FUJITSU_S702X, ALC260_ACER, + ALC260_WILL, + ALC260_REPLACER_672V, #ifdef CONFIG_SND_DEBUG ALC260_TEST, #endif @@ -115,15 +117,28 @@ enum { ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, + ALC861VD_LENOVO, ALC861VD_AUTO, ALC861VD_MODEL_LAST, }; +/* ALC662 models */ +enum { + ALC662_3ST_2ch_DIG, + ALC662_3ST_6ch_DIG, + ALC662_3ST_6ch, + ALC662_5ST_DIG, + ALC662_LENOVO_101E, + ALC662_AUTO, + ALC662_MODEL_LAST, +}; + /* ALC882 models */ enum { ALC882_3ST_DIG, ALC882_6ST_DIG, ALC882_ARIMA, + ALC882_W2JC, ALC882_AUTO, ALC885_MACPRO, ALC882_MODEL_LAST, @@ -141,6 +156,7 @@ enum { ALC883_ACER, ALC883_MEDION, ALC883_LAPTOP_EAPD, + ALC883_LENOVO_101E_2ch, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -163,7 +179,7 @@ struct alc_spec { struct hda_pcm_stream *stream_analog_playback; struct hda_pcm_stream *stream_analog_capture; - char *stream_name_digital; /* digital PCM stream */ + char *stream_name_digital; /* digital PCM stream */ struct hda_pcm_stream *stream_digital_playback; struct hda_pcm_stream *stream_digital_capture; @@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) + if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) val = alc_pin_mode_min(dir); change = pinctl != alc_pin_mode_values[val]; @@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec, spec->multiout.hp_nid = preset->hp_nid; spec->num_mux_defs = preset->num_mux_defs; - if (! spec->num_mux_defs) + if (!spec->num_mux_defs) spec->num_mux_defs = 1; spec->input_mux = preset->input_mux; @@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec, spec->init_hook = preset->init_hook; } +/* Enable GPIO mask and set output */ +static struct hda_verb alc_gpio1_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, + { } +}; + +static struct hda_verb alc_gpio2_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, + { } +}; + +static struct hda_verb alc_gpio3_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + { } +}; + +/* 32-bit subsystem ID for BIOS loading in HD Audio codec. + * 31 ~ 16 : Manufacture ID + * 15 ~ 8 : SKU ID + * 7 ~ 0 : Assembly ID + * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 + */ +static void alc_subsystem_id(struct hda_codec *codec, + unsigned int porta, unsigned int porte, + unsigned int portd) +{ + unsigned int ass, tmp; + + ass = codec->subsystem_id; + if (!(ass & 1)) + return; + + /* Override */ + tmp = (ass & 0x38) >> 3; /* external Amp control */ + switch (tmp) { + case 1: + snd_hda_sequence_write(codec, alc_gpio1_init_verbs); + break; + case 3: + snd_hda_sequence_write(codec, alc_gpio2_init_verbs); + break; + case 7: + snd_hda_sequence_write(codec, alc_gpio3_init_verbs); + break; + case 5: + switch (codec->vendor_id) { + case 0x10ec0862: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0267: + case 0x10ec0268: + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + return; + } + case 6: + if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ + hda_nid_t port = 0; + tmp = (ass & 0x1800) >> 11; + switch (tmp) { + case 0: port = porta; break; + case 1: port = porte; break; + case 2: port = portd; break; + } + if (port) + snd_hda_codec_write(codec, port, 0, + AC_VERB_SET_EAPD_BTLENABLE, + 2); + } + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, + (tmp == 5 ? 0x3040 : 0x3050)); + break; + } +} + /* * ALC880 3-stack model * @@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { static hda_nid_t alc880_6st_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 -}; +}; static struct hda_input_mux alc880_6stack_capture_source = { .num_items = 4, @@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = { }; /* toggle speaker-output according to the hp-jack state */ -static void alc880_uniwill_automute(struct hda_codec *codec) +static void alc880_uniwill_hp_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); +} + +/* auto-toggle front mic */ +static void alc880_uniwill_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc880_uniwill_automute(struct hda_codec *codec) +{ + alc880_uniwill_hp_automute(codec); + alc880_uniwill_mic_automute(codec); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, /* Looks like the unsol event is incompatible with the standard * definition. 4bit tag is placed at 28 bit! */ - if ((res >> 28) == ALC880_HP_EVENT || - (res >> 28) == ALC880_MIC_EVENT) - alc880_uniwill_automute(codec); + switch (res >> 28) { + case ALC880_HP_EVENT: + alc880_uniwill_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc880_uniwill_mic_automute(codec); + break; + } } static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) @@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, */ if ((res >> 28) == ALC880_HP_EVENT) alc880_uniwill_p53_hp_automute(codec); - if ((res >> 28) == ALC880_DCVOL_EVENT) + if ((res >> 28) == ALC880_DCVOL_EVENT) alc880_uniwill_p53_dcvol_automute(codec); } @@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { }; /* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio1_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - - { } -}; - -/* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio2_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, - - { } -}; +#define alc880_gpio1_init_verbs alc_gpio1_init_verbs +#define alc880_gpio2_init_verbs alc_gpio2_init_verbs /* Clevo m520g init */ static struct hda_verb alc880_pin_clevo_init_verbs[] = { @@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = { static void alc880_lg_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { static void alc880_lg_lw_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_open(codec, &spec->multiout); } +static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) @@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { /* NID is set in alc_build_pcms */ .ops = { .open = alc880_dig_playback_pcm_open, - .close = alc880_dig_playback_pcm_close + .close = alc880_dig_playback_pcm_close, + .prepare = alc880_dig_playback_pcm_prepare }, }; @@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec) struct alc_spec *spec = codec->spec; unsigned int i; - if (! spec) + if (!spec) return; if (spec->kctl_alloc) { @@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { static struct alc_config_preset alc880_presets[] = { [ALC880_3ST] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), @@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_3ST_DIG] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer}, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), @@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST_DIG] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), @@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST_DIG] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_W810] = { .mixers = { alc880_w810_base_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_w810_init_verbs, alc880_gpio2_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), .dac_nids = alc880_w810_dac_nids, @@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_Z71V] = { .mixers = { alc880_z71v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_z71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), .dac_nids = alc880_z71v_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_F1734] = { .mixers = { alc880_f1734_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_f1734_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), .dac_nids = alc880_f1734_dac_nids, .hp_nid = 0x02, @@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG2] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio2_init_verbs }, /* use GPIO2 */ .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_W1V] = { .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = { .init_hook = alc880_uniwill_p53_hp_automute, }, [ALC880_FUJITSU] = { - .mixers = { alc880_fujitsu_mixer, + .mixers = { alc880_fujitsu_mixer, alc880_pcbeep_mixer, }, .init_verbs = { alc880_volume_init_verbs, alc880_uniwill_p53_init_verbs, @@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = { .mixers = { alc880_lg_lw_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_lg_lw_init_verbs }, - .num_dacs = 1, + .num_dacs = 1, .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), @@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = { }; /* add dynamic controls */ -static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) +static int add_control(struct alc_spec *spec, int type, const char *name, + unsigned long val) { struct snd_kcontrol_new *knew; if (spec->num_kctl_used >= spec->num_kctl_alloc) { int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; - knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ - if (! knew) + /* array + terminator */ + knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); + if (!knew) return -ENOMEM; if (spec->kctl_alloc) { - memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); + memcpy(knew, spec->kctl_alloc, + sizeof(*knew) * spec->num_kctl_alloc); kfree(spec->kctl_alloc); } spec->kctl_alloc = knew; @@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign knew = &spec->kctl_alloc[spec->num_kctl_used]; *knew = alc880_control_templates[type]; knew->name = kstrdup(name, GFP_KERNEL); - if (! knew->name) + if (!knew->name) return -ENOMEM; knew->private_value = val; spec->num_kctl_used++; @@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign #define ALC880_PIN_CD_NID 0x1c /* fill in the dac_nids table from the parsed pin configuration */ -static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc880_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int assigned[4]; @@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi continue; /* search for an empty channel */ for (j = 0; j < cfg->line_outs; j++) { - if (! assigned[j]) { - spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); + if (!assigned[j]) { + spec->multiout.dac_nids[i] = + alc880_idx_to_dac(j); assigned[j] = 1; break; } @@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid; else spec->multiout.extra_out_nid[0] = nid; /* control HP volume/switch on the output mixer amp */ nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; } /* create input playback/capture controls for the given pin */ -static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, +static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, + const char *ctlname, int idx, hda_nid_t mix_nid) { char name[32]; int err; sprintf(name, "%s Playback Volume", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; return 0; } @@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, idx, 0x0b); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); imux->num_items++; } } @@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (alc880_is_multi_pin(nid)) { struct alc_spec *spec = codec->spec; @@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, } } +static int get_pin_type(int line_out_type) +{ + if (line_out_type == AUTO_PIN_HP_OUT) + return PIN_HP; + else + return PIN_OUT; +} + static void alc880_auto_init_multi_out(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int i; - + + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; - alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); } } @@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc880_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC880_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } } /* parse the BIOS configuration and set up the alc_spec */ -/* return 1 if successful, 0 if the proper config is not found, or a negative error code */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc880_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc880_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc880_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], - "Speaker")) < 0 || - (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], - "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using 3-stack mode...\n"); @@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec) spec->stream_digital_playback = &alc880_pcm_digital_playback; spec->stream_digital_capture = &alc880_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc880_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc880_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc880_adc_nids; @@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), { } /* end */ -}; +}; static struct snd_kcontrol_new alc260_input_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), @@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { { } /* end */ }; +/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, + * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. + */ +static struct snd_kcontrol_new alc260_will_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), + { } /* end */ +}; + +/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, + * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. + */ +static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + { } /* end */ +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc260_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), @@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = { {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* unmute LINE-2 out pin */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* mute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* mute Line In */ @@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = { {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ + /* Unmute Line-out pin widget amp left and right + * (no equiv mixer ctrl) + */ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = { { } }; +static struct hda_verb alc260_will_verbs[] = { + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, + {} +}; + +static struct hda_verb alc260_replacer_672v_verbs[] = { + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, + + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + + {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc260_replacer_672v_automute(struct hda_codec *codec) +{ + unsigned int present; + + /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ + present = snd_hda_codec_read(codec, 0x0f, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + } else { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc260_replacer_672v_automute(codec); +} + /* Test configuration for debugging, modelled after the ALC880 test * configuration. */ @@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, return 0; /* N/A */ snprintf(name, sizeof(name), "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); + if (err < 0) return err; snprintf(name, sizeof(name), "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); + if (err < 0) return err; return 1; } @@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, if (err < 0) return err; } - return 0; + return 0; } /* create playback/capture controls for input pins */ @@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, if (cfg->input_pins[i] >= 0x12) { idx = cfg->input_pins[i] - 0x12; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } - if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ + if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ idx = cfg->input_pins[i] - 0x09; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } @@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, int sel_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (nid >= 0x12) { int idx = nid - 0x12; snd_hda_codec_write(codec, idx + 0x0b, 0, AC_VERB_SET_CONNECT_SEL, sel_idx); - } } @@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t nid; - nid = spec->autocfg.line_out_pins[0]; - if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); + alc_subsystem_id(codec, 0x10, 0x15, 0x0f); + nid = spec->autocfg.line_out_pins[0]; + if (nid) { + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); + } nid = spec->autocfg.speaker_pins[0]; if (nid) @@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) nid = spec->autocfg.hp_pins[0]; if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); -} + alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); +} #define ALC260_PIN_CD_NID 0x16 static void alc260_auto_init_analog_input(struct hda_codec *codec) @@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (nid >= 0x12) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC260_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc260_ignore[] = { 0x17, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc260_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc260_ignore); + if (err < 0) return err; - if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) return err; - if (! spec->kctl_alloc) + if (!spec->kctl_alloc) return 0; /* can't find valid BIOS pin config */ - if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = 2; @@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { [ALC260_HP_3013] = "hp-3013", [ALC260_FUJITSU_S702X] = "fujitsu", [ALC260_ACER] = "acer", + [ALC260_WILL] = "will", + [ALC260_REPLACER_672V] = "replacer", #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = "test", #endif @@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), + SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), + SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), {} }; @@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = { .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), .input_mux = alc260_acer_capture_sources, }, + [ALC260_WILL] = { + .mixers = { alc260_will_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_will_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + }, + [ALC260_REPLACER_672V] = { + .mixers = { alc260_replacer_672v_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + .unsol_event = alc260_replacer_672v_unsol_event, + .init_hook = alc260_replacer_672v_automute, + }, #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = { .mixers = { alc260_test_mixer, @@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = { #define alc882_mux_enum_info alc_mux_enum_info #define alc882_mux_enum_get alc_mux_enum_get -static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; @@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc882_w2jc_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = { /* change to EAPD mode */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, - { } + { } }; /* Mac Pro test */ @@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; + static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) { unsigned int gpiostate, gpiomask, gpiodir; @@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_3ST_DIG] = "3stack-dig", [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", + [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", [ALC882_AUTO] = "auto", }; @@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), {} }; @@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_sixstack_modes, .input_mux = &alc882_capture_source, }, + [ALC882_W2JC] = { + .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, + .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, + alc880_gpio1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), + .channel_mode = alc880_threestack_modes, + .need_dac_fix = 1, + .input_mux = &alc882_capture_source, + .dig_out_nid = ALC882_DIGOUT_NID, + }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, .init_verbs = { alc882_macpro_init_verbs }, @@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else idx = spec->multiout.dac_nids[dac_idx] - 2; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); } @@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc882_auto_set_output_and_unmute(codec, nid, pin_type, + i); } } @@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ + /* use dac 0 */ + alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); } #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) @@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc882_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC882_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec) spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc882_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc882_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc882_adc_nids; @@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = { /* ADC1-2 */ 0x08, 0x09, }; + /* input MUX */ /* FIXME: should be a matrix-type input source selection */ @@ -5045,7 +5432,16 @@ static struct hda_input_mux alc883_capture_source = { { "CD", 0x4 }, }, }; -#define alc883_mux_enum_info alc_mux_enum_info + +static struct hda_input_mux alc883_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; + +#define alc883_mux_enum_info alc_mux_enum_info #define alc883_mux_enum_get alc_mux_enum_get static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, @@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, *cur_val = idx; return 1; } + /* * 2ch mode */ @@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; + +static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; static struct snd_kcontrol_new alc883_chmode_mixer[] = { { @@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = { {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + + { } /* end */ +}; +static struct hda_verb alc883_lenovo_101e_verbs[] = { + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, { } /* end */ }; @@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = { static void alc883_tagra_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); + 0x80, bits); + snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, + present ? 1 : 3); } static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) @@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) alc883_tagra_automute(codec); } +static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc883_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc883_lenovo_101e_ispeaker_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = { {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Input mixer2 */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, { } @@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_ACER] = "acer", [ALC883_MEDION] = "medion", [ALC883_LAPTOP_EAPD] = "laptop-eapd", + [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_AUTO] = "auto", }; @@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), @@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch), {} }; @@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_3ST_6ch] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_6ST_DIG] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, }, + [ALC883_LENOVO_101E_2ch] = { + .mixers = { alc883_lenovo_101e_2ch_mixer}, + .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_lenovo_101e_capture_source, + .unsol_event = alc883_lenovo_101e_unsol_event, + .init_hook = alc883_lenovo_101e_all_automute, + }, }; @@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else @@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc883_auto_set_output_and_unmute(codec, nid, pin_type, + i); } } @@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) else if (err > 0) /* hack - override the init verbs */ spec->init_verbs[0] = alc883_auto_init_verbs; - spec->mixers[spec->num_mixers] = alc883_capture_mixer; - spec->num_mixers++; + spec->mixers[spec->num_mixers] = alc883_capture_mixer; + spec->num_mixers++; return err; } @@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = alc883_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); } @@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, { } }; @@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = { }; /* add playback controls from the parsed DAC table */ -static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int err; @@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct nid = cfg->line_out_pins[0]; if (nid) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Front Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } nid = cfg->speaker_pins[0]; if (nid) { if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Speaker Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct if (nid) { /* spec->multiout.hp_nid = 2; */ if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } - return 0; + return 0; } /* identical with ALC880 */ -#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls +#define alc262_auto_create_analog_input_ctls \ + alc880_auto_create_analog_input_ctls /* * generic initialization of ADC, input mixers and output mixers @@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc262_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc262_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WF] = { .mixers = { alc262_HP_BPC_WildWest_mixer }, .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, @@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WL] = { .mixers = { alc262_HP_BPC_WildWest_mixer, alc262_HP_BPC_WildWest_option_mixer }, @@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_BENQ_ED8] = { .mixers = { alc262_base_mixer }, .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, @@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - }, + }, }; static int patch_alc262(struct hda_codec *codec) @@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec) codec->spec = spec; #if 0 - /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ + /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is + * under-run + */ { int tmp; snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc262_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc262_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc262_adc_nids; @@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec) static struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { static struct hda_verb alc861_asus_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { /* output mixer control */ @@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_asus_mixer[] = { /* output mixer control */ @@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ - + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } @@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ - /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ + /* port-A for surround (rear panel) + * according to codec#0 this is the HP jack + */ { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ /* route front PCM to HP */ { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ -// {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* Unmute DAC0~3 & spdif out*/ @@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 + {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ { } }; static struct hda_verb alc861_toshiba_init_verbs[] = { {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - + { } }; @@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec) static void alc861_toshiba_unsol_event(struct hda_codec *codec, unsigned int res) { - /* Looks like the unsol event is incompatible with the standard - * definition. 6bit tag is placed at 26 bit! - */ if ((res >> 26) == ALC880_HP_EVENT) alc861_toshiba_automute(codec); } @@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = { }; /* fill in the dac_nids table from the parsed pin configuration */ -static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { int i; hda_nid_t nid; @@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, idx, err; for (i = 0; i < cfg->line_outs; i++) { nid = spec->multiout.dac_nids[i]; - if (! nid) + if (!nid) continue; if (nid == 0x05) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) + for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; + idx++) if (nid == alc861_dac_nids[idx]) break; sprintf(name, "%s Playback Switch", chname[idx]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) int err; hda_nid_t nid; - if (! pin) + if (!pin) return 0; if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { nid = 0x03; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; spec->multiout.hp_nid = nid; } @@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) } /* create playback/capture controls for input pins */ -static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { struct hda_input_mux *imux = &spec->private_imux; int i, err, idx, idx1; for (i = 0; i < AUTO_PIN_LAST; i++) { - switch(cfg->input_pins[i]) { + switch (cfg->input_pins[i]) { case 0x0c: idx1 = 1; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0f: idx1 = 2; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0d: idx1 = 0; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; - case 0x10: + case 0x10: idx1 = 3; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; case 0x11: idx1 = 4; - idx = 0; // CD + idx = 0; /* CD */ break; default: continue; @@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx1; - imux->num_items++; + imux->num_items++; } return 0; } @@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = { { } /* end */ }; -static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, +static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); } @@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); + alc861_auto_set_output_and_unmute(codec, nid, pin_type, + spec->multiout.dac_nids[i]); } } @@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); + alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, + spec->multiout.dac_nids[0]); } static void alc861_auto_init_analog_input(struct hda_codec *codec) @@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; - if ((nid>=0x0c) && (nid <=0x11)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + if (nid >= 0x0c && nid <= 0x11) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); } } } /* parse the BIOS configuration and set up the alc_spec */ -/* return 1 if successful, 0 if the proper config is not found, or a negative error code */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc861_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 || - (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); + if (err < 0) + return err; + err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), + SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), + SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), {} }; @@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = { }, [ALC861_TOSHIBA] = { .mixers = { alc861_toshiba_mixer }, - .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, + .init_verbs = { alc861_base_init_verbs, + alc861_toshiba_init_verbs }, .num_dacs = ARRAY_SIZE(alc861_dac_nids), .dac_nids = alc861_dac_nids, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), @@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - codec->spec = spec; + codec->spec = spec; board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, alc861_models, @@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ + HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), + + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + + { } /* end */ +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, /* * Set up output mixers (0x02 - 0x05) @@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { { } }; +static struct hda_verb alc861vd_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + +static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc861vd_lenovo_automute(struct hda_codec *codec) +{ + alc861vd_lenovo_hp_automute(codec); + alc861vd_lenovo_mic_automute(codec); +} + +static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc861vd_lenovo_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc861vd_lenovo_mic_automute(codec); + break; + } +} + /* pcm configuration: identiacal with ALC880 */ #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture @@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", + [ALC861VD_LENOVO] = "lenovo", [ALC861VD_AUTO] = "auto", }; static struct snd_pci_quirk alc861vd_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), - SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), + SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), {} }; @@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = { .channel_mode = alc861vd_6stack_modes, .input_mux = &alc861vd_capture_source, }, + [ALC861VD_LENOVO] = { + .mixers = { alc861vd_lenovo_mixer }, + .init_verbs = { alc861vd_volume_init_verbs, + alc861vd_3stack_init_verbs, + alc861vd_eapd_verbs, + alc861vd_lenovo_unsol_verbs }, + .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), + .dac_nids = alc660vd_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), + .adc_nids = alc861vd_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), + .channel_mode = alc861vd_3stack_2ch_modes, + .input_mux = &alc861vd_capture_source, + .unsol_event = alc861vd_lenovo_unsol_event, + .init_hook = alc861vd_lenovo_automute, + }, }; /* @@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) alc861vd_auto_set_output_and_unmute(codec, nid, - PIN_OUT, i); + pin_type, i); } } @@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid_v = alc861vd_idx_to_mixer_vol( alc880_dac_to_idx( @@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 1, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 2, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 1, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 2, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid_v; else spec->multiout.extra_out_nid[0] = nid_v; @@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, - HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; @@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861vd_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861vd_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_multi_out_ctls(spec, - &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], "Speaker")) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.hp_pins[0], "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, - &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -8674,6 +9362,861 @@ static int patch_alc861vd(struct hda_codec *codec) return 0; } +/* + * ALC662 support + * + * ALC662 is almost identical with ALC880 but has cleaner and more flexible + * configuration. Each pin widget can choose any input DACs and a mixer. + * Each ADC is connected from a mixer of all inputs. This makes possible + * 6-channel independent captures. + * + * In addition, an independent DAC for the multi-playback (not used in this + * driver yet). + */ +#define ALC662_DIGOUT_NID 0x06 +#define ALC662_DIGIN_NID 0x0a + +static hda_nid_t alc662_dac_nids[4] = { + /* front, rear, clfe, rear_surr */ + 0x02, 0x03, 0x04 +}; + +static hda_nid_t alc662_adc_nids[1] = { + /* ADC1-2 */ + 0x09, +}; +/* input MUX */ +/* FIXME: should be a matrix-type input source selection */ + +static struct hda_input_mux alc662_capture_source = { + .num_items = 4, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x2 }, + { "CD", 0x4 }, + }, +}; + +static struct hda_input_mux alc662_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; +#define alc662_mux_enum_info alc_mux_enum_info +#define alc662_mux_enum_get alc_mux_enum_get + +static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + const struct hda_input_mux *imux = spec->input_mux; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; + hda_nid_t nid = capture_mixers[adc_idx]; + unsigned int *cur_val = &spec->cur_mux[adc_idx]; + unsigned int i, idx; + + idx = ucontrol->value.enumerated.item[0]; + if (idx >= imux->num_items) + idx = imux->num_items - 1; + if (*cur_val == idx && !codec->in_resume) + return 0; + for (i = 0; i < imux->num_items; i++) { + unsigned int v = (i == idx) ? 0x7000 : 0x7080; + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + v | (imux->items[i].index << 8)); + } + *cur_val = idx; + return 1; +} +/* + * 2ch mode + */ +static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { + { 2, NULL } +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_3ST_ch2_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_3ST_ch6_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { + { 2, alc662_3ST_ch2_init }, + { 6, alc662_3ST_ch6_init }, +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_sixstack_ch6_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_sixstack_ch8_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_5stack_modes[2] = { + { 2, alc662_sixstack_ch6_init }, + { 6, alc662_sixstack_ch8_init }, +}; + +/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 + * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b + */ + +static struct snd_kcontrol_new alc662_base_mixer[] = { + /* output mixer control */ + HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + /*Input mixer control */ + HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), + + /* Capture mixer control */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = alc_mux_enum_info, + .get = alc_mux_enum_get, + .put = alc_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_chmode_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Channel Mode", + .info = alc_ch_mode_info, + .get = alc_ch_mode_get, + .put = alc_ch_mode_put, + }, + { } /* end */ +}; + +static struct hda_verb alc662_init_verbs[] = { + /* ADC: mute amp left and right */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Front mixer: unmute input/output amp left and right (volume = 0) */ + + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Front Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Rear Pin: output 1 (0x0d) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* CLFE Pin: output 2 (0x0e) */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Mic (rear) pin: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Front Mic pin: input vref at 80% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line In pin: input */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line-2 In: Headphone output (output 0 - 0x0c) */ + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* CD pin widget for input */ + {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + { } +}; + +static struct hda_verb alc662_sue_init_verbs[] = { + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, + {} +}; + +/* + * generic initialization of ADC, input mixers and output mixers + */ +static struct hda_verb alc662_auto_init_verbs[] = { + /* + * Unmute ADC and set the default input to mic-in + */ + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + * mixer widget + * Note: PASD motherboards uses the Line In 2 as the input for front + * panel mic (mic 2) + */ + /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* + * Set up output mixers (0x0c - 0x0f) + */ + /* set vol=0 to output mixers */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + + /* set up input amps for analog loopback */ + /* Amp Indices: DAC = 0, mixer = 1 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + { } +}; + +/* capture mixer elements */ +static struct snd_kcontrol_new alc662_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + * FIXME: the controls appear in the "playback" view! + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc882_mux_enum_info, + .get = alc882_mux_enum_get, + .put = alc882_mux_enum_put, + }, + { } /* end */ +}; + +static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc662_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc662_lenovo_101e_ispeaker_automute(codec); +} + + +/* pcm configuration: identiacal with ALC880 */ +#define alc662_pcm_analog_playback alc880_pcm_analog_playback +#define alc662_pcm_analog_capture alc880_pcm_analog_capture +#define alc662_pcm_digital_playback alc880_pcm_digital_playback +#define alc662_pcm_digital_capture alc880_pcm_digital_capture + +/* + * configuration and preset + */ +static const char *alc662_models[ALC662_MODEL_LAST] = { + [ALC662_3ST_2ch_DIG] = "3stack-dig", + [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", + [ALC662_3ST_6ch] = "3stack-6ch", + [ALC662_5ST_DIG] = "6stack-dig", + [ALC662_LENOVO_101E] = "lenovo-101e", + [ALC662_AUTO] = "auto", +}; + +static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + {} +}; + +static struct alc_config_preset alc662_presets[] = { + [ALC662_3ST_2ch_DIG] = { + .mixers = { alc662_3ST_2ch_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch_DIG] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_5ST_DIG] = { + .mixers = { alc662_base_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), + .channel_mode = alc662_5stack_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_LENOVO_101E] = { + .mixers = { alc662_lenovo_101e_mixer }, + .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_lenovo_101e_capture_source, + .unsol_event = alc662_lenovo_101e_unsol_event, + .init_hook = alc662_lenovo_101e_all_automute, + }, + +}; + + +/* + * BIOS auto configuration + */ + +/* add playback controls from the parsed DAC table */ +static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + char name[32]; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; + hda_nid_t nid; + int i, err; + + for (i = 0; i < cfg->line_outs; i++) { + if (!spec->multiout.dac_nids[i]) + continue; + nid = alc880_idx_to_dac(i); + if (i == 2) { + /* Center/LFE */ + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); + if (err < 0) + return err; + } else { + sprintf(name, "%s Playback Volume", chname[i]); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", chname[i]); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) + return err; + } + } + return 0; +} + +/* add playback controls for speaker and HP outputs */ +static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, + const char *pfx) +{ + hda_nid_t nid; + int err; + char name[32]; + + if (!pin) + return 0; + + if (alc880_is_fixed_pin(pin)) { + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + /* printk("DAC nid=%x\n",nid); */ + /* specify the DAC as the extra output */ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else + spec->multiout.extra_out_nid[0] = nid; + /* control HP volume/switch on the output mixer amp */ + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + sprintf(name, "%s Playback Volume", pfx); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) + return err; + } else if (alc880_is_multi_pin(pin)) { + /* set manual connection */ + /* we have only a switch on HP-out PIN */ + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + return 0; +} + +/* create playback/capture controls for input pins */ +static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + struct hda_input_mux *imux = &spec->private_imux; + int i, err, idx; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (alc880_is_input_pin(cfg->input_pins[i])) { + idx = alc880_input_pin_idx(cfg->input_pins[i]); + err = new_analog_input(spec, cfg->input_pins[i], + auto_pin_cfg_labels[i], + idx, 0x0b); + if (err < 0) + return err; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); + imux->num_items++; + } + } + return 0; +} + +static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, + int dac_idx) +{ + /* set as output */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + /* need the manual connection? */ + if (alc880_is_multi_pin(nid)) { + struct alc_spec *spec = codec->spec; + int idx = alc880_multi_pin_idx(nid); + snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, + AC_VERB_SET_CONNECT_SEL, + alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); + } +} + +static void alc662_auto_init_multi_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i <= HDA_SIDE; i++) { + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); + if (nid) + alc662_auto_set_output_and_unmute(codec, nid, pin_type, + i); + } +} + +static void alc662_auto_init_hp_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t pin; + + pin = spec->autocfg.hp_pins[0]; + if (pin) /* connect to front */ + /* use dac 0 */ + alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); +} + +#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) +#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID + +static void alc662_auto_init_analog_input(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = spec->autocfg.input_pins[i]; + if (alc662_is_input_pin(nid)) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + (i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN)); + if (nid != ALC662_PIN_CD_NID) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_MUTE); + } + } +} + +static int alc662_parse_auto_config(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int err; + static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc662_ignore); + if (err < 0) + return err; + if (!spec->autocfg.line_outs) + return 0; /* can't find valid BIOS pin config */ + + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + + spec->multiout.max_channels = spec->multiout.num_dacs * 2; + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->num_mux_defs = 1; + spec->input_mux = &spec->private_imux; + + if (err < 0) + return err; + else if (err > 0) + /* hack - override the init verbs */ + spec->init_verbs[0] = alc662_auto_init_verbs; + spec->mixers[spec->num_mixers] = alc662_capture_mixer; + spec->num_mixers++; + return err; +} + +/* additional initialization for auto-configuration model */ +static void alc662_auto_init(struct hda_codec *codec) +{ + alc662_auto_init_multi_out(codec); + alc662_auto_init_hp_out(codec); + alc662_auto_init_analog_input(codec); +} + +static int patch_alc662(struct hda_codec *codec) +{ + struct alc_spec *spec; + int err, board_config; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + + codec->spec = spec; + + board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, + alc662_models, + alc662_cfg_tbl); + if (board_config < 0) { + printk(KERN_INFO "hda_codec: Unknown model for ALC662, " + "trying auto-probe from BIOS...\n"); + board_config = ALC662_AUTO; + } + + if (board_config == ALC662_AUTO) { + /* automatic parse from the BIOS config */ + err = alc662_parse_auto_config(codec); + if (err < 0) { + alc_free(codec); + return err; + } else if (err) { + printk(KERN_INFO + "hda_codec: Cannot set up configuration " + "from BIOS. Using base mode...\n"); + board_config = ALC662_3ST_2ch_DIG; + } + } + + if (board_config != ALC662_AUTO) + setup_preset(spec, &alc662_presets[board_config]); + + spec->stream_name_analog = "ALC662 Analog"; + spec->stream_analog_playback = &alc662_pcm_analog_playback; + spec->stream_analog_capture = &alc662_pcm_analog_capture; + + spec->stream_name_digital = "ALC662 Digital"; + spec->stream_digital_playback = &alc662_pcm_digital_playback; + spec->stream_digital_capture = &alc662_pcm_digital_capture; + + if (!spec->adc_nids && spec->input_mux) { + spec->adc_nids = alc662_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); + } + + codec->patch_ops = alc_patch_ops; + if (board_config == ALC662_AUTO) + spec->init_hook = alc662_auto_init; + + return 0; +} + /* * patch entries */ @@ -8681,10 +10224,14 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", - .patch = patch_alc861 }, + .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, + { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", + .patch = patch_alc883 }, + { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", + .patch = patch_alc662 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index c94291bc5367..93ae9c250767 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -62,6 +62,7 @@ enum { STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, + STAC_IMAC_INTEL, STAC_922X_MODELS }; @@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; -static hda_nid_t stac9205_dmic_nids[3] = { - 0x17, 0x18, 0 +static hda_nid_t stac9205_dmic_nids[2] = { + 0x17, 0x18, }; static hda_nid_t stac9200_pin_nids[8] = { @@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int macbook_pin_configs[10] = { - 0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110, - 0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e, - 0x400000fc, 0x400000fb, -}; - static unsigned int macbook_pro_v1_pin_configs[10] = { 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, @@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = { 0x400000fc, 0x400000fb, }; +static unsigned int imac_intel_pin_configs[10] = { + 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, + 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, + 0x400000fc, 0x400000fb, +}; + static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_MACMINI] = d945gtp5_pin_configs, - [STAC_MACBOOK] = macbook_pin_configs, + [STAC_MACMINI] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, + [STAC_IMAC_INTEL] = imac_intel_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { @@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", + [STAC_IMAC_INTEL] = "imac-intel", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture callbacks @@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { /* NID is set in stac92xx_build_pcms */ .ops = { .open = stac92xx_dig_playback_pcm_open, - .close = stac92xx_dig_playback_pcm_close + .close = stac92xx_dig_playback_pcm_close, + .prepare = stac92xx_dig_playback_pcm_prepare }, }; @@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; + unsigned int wcaps, wtype; + int i, num_dacs = 0; + + /* use the wcaps cache to count all DACs available for line-outs */ + for (i = 0; i < codec->num_nodes; i++) { + wcaps = codec->wcaps[i]; + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) + num_dacs++; + } + snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); + switch (cfg->line_outs) { case 3: /* add line-in as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; @@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 2: /* add line-in as clfe and mic as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 1: /* add line-in as surr and mic as clfe */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf return 0; } + +static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{ + int i; + + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (spec->multiout.dac_nids[i] == nid) + return 1; + } + + return 0; +} + /* - * XXX The line_out pin widget connection list may not be set to the - * desired DAC nid. This is the case on 927x where ports A and B can - * be routed to several DACs. - * - * This requires an analysis of the line-out/hp pin configuration - * to provide a best fit for pin/DAC configurations that are routable. - * For now, 927x DAC4 is not supported and 927x DAC1 output to ports - * A and B is not supported. + * Fill in the dac_nids table from the parsed pin configuration + * This function only works when every pin in line_out_pins[] + * contains atleast one DAC in its connection list. Some 92xx + * codecs are not connected directly to a DAC, such as the 9200 + * and 9202/925x. For those, dac_nids[] must be hard-coded. */ -/* fill in the dac_nids table from the parsed pin configuration */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; - hda_nid_t nid; - int i; - - /* check the pins hardwired to audio widget */ + int i, j, conn_len = 0; + hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; + unsigned int wcaps, wtype; + for (i = 0; i < cfg->line_outs; i++) { nid = cfg->line_out_pins[i]; - spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - } + conn_len = snd_hda_get_connections(codec, nid, conn, + HDA_MAX_CONNECTIONS); + for (j = 0; j < conn_len; j++) { + wcaps = snd_hda_param_read(codec, conn[j], + AC_PAR_AUDIO_WIDGET_CAP); + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + + if (wtype != AC_WID_AUD_OUT || + (wcaps & AC_WCAP_DIGITAL)) + continue; + /* conn[j] is a DAC routed to this line-out */ + if (!is_in_dac_nids(spec, conn[j])) + break; + } + + if (j == conn_len) { + /* error out, no available DAC found */ + snd_printk(KERN_ERR + "%s: No available DAC for pin 0x%x\n", + __func__, nid); + return -ENODEV; + } - spec->multiout.num_dacs = cfg->line_outs; + spec->multiout.dac_nids[i] = conn[j]; + spec->multiout.num_dacs++; + if (conn_len > 1) { + /* select this DAC in the pin's input mux */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, j); + + } + } + snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", + spec->multiout.num_dacs, + spec->multiout.dac_nids[0], + spec->multiout.dac_nids[1], + spec->multiout.dac_nids[2], + spec->multiout.dac_nids[3], + spec->multiout.dac_nids[4]); return 0; } @@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) { - int i; - - for (i = 0; i < spec->multiout.num_dacs; i++) { - if (spec->multiout.dac_nids[i] == nid) - return 1; - } + if (is_in_dac_nids(spec, nid)) + return 1; if (spec->multiout.hp_nid == nid) return 1; return 0; @@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, add_spec_dacs(spec, nid); } for (i = 0; i < cfg->speaker_outs; i++) { - nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, + nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; if (check_in_dac_nids(spec, nid)) nid = 0; - if (check_in_dac_nids(spec, nid)) - nid = 0; if (! nid) continue; add_spec_dacs(spec, nid); @@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const imux->num_items++; } - if (imux->num_items == 1) { + if (imux->num_items) { /* * Set the current input for the muxes. * The STAC9221 has two input muxes with identical source @@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) - return; + + /* if setting pin direction bits, clear the current + direction bits first */ + if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) + pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl | flag); @@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec) stac92xx_init(codec); stac92xx_set_config_regs(codec); + snd_hda_resume_ctls(codec, spec->mixer); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); if (spec->multiout.dig_out_nid) @@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec) */ printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { + case 0x106b0a00: /* MacBook First generatoin */ + spec->board_config = STAC_MACBOOK; + break; case 0x106b0200: /* MacBook Pro first generation */ spec->board_config = STAC_MACBOOK_PRO_V1; break; case 0x106b1e00: /* MacBook Pro second generation */ spec->board_config = STAC_MACBOOK_PRO_V2; break; + case 0x106b0700: /* Intel-based iMac */ + spec->board_config = STAC_IMAC_INTEL; + break; } } @@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); spec->num_dmics = 0; spec->init = stac922x_core_init; @@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_3ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_5ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec) default: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = stac927x_core_init; spec->mixer = stac927x_mixer; @@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec) spec->adc_nids = stac9205_adc_nids; spec->mux_nids = stac9205_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); spec->dmic_nids = stac9205_dmic_nids; - spec->num_dmics = 2; + spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids); spec->dmux_nid = 0x1d; spec->init = stac9205_core_init; @@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), + SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), {} }; diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 2b11ac8689b9..ba32d1e52cb8 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct via_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture */ @@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { /* NID is set in via_build_pcms */ .ops = { .open = via_dig_playback_pcm_open, - .close = via_dig_playback_pcm_close + .close = via_dig_playback_pcm_close, + .prepare = via_dig_playback_pcm_prepare }, }; diff --git a/trunk/sound/pci/ice1712/amp.c b/trunk/sound/pci/ice1712/amp.c index 6e22d326df32..44bbb630b949 100644 --- a/trunk/sound/pci/ice1712/amp.c +++ b/trunk/sound/pci/ice1712/amp.c @@ -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..66bacde1ead3 100644 --- a/trunk/sound/pci/ice1712/aureon.c +++ b/trunk/sound/pci/ice1712/aureon.c @@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl * mixers */ -static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { }; -static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { +static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), @@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char aureon51_eeprom[] __devinitdata = { +static unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char aureon71_eeprom[] __devinitdata = { +static unsigned char aureon71_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = { }; #define prodigy71_eeprom aureon71_eeprom -static const unsigned char prodigy71lt_eeprom[] __devinitdata = { +static unsigned char prodigy71lt_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = { #define prodigy71xt_eeprom prodigy71lt_eeprom /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, .name = "Terratec Aureon 5.1-Sky", diff --git a/trunk/sound/pci/ice1712/aureon.h b/trunk/sound/pci/ice1712/aureon.h index 79e58e88ed47..c253b8e2c789 100644 --- a/trunk/sound/pci/ice1712/aureon.h +++ b/trunk/sound/pci/ice1712/aureon.h @@ -38,7 +38,7 @@ #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ #define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ -extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; /* GPIO bits */ #define AUREON_CS8415_CS (1 << 22) 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 e47861ccd6e7..2697156607e4 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..8203562ef7e7 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", 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..6630a0ae9527 100644 --- a/trunk/sound/pci/ice1712/ice1712.c +++ b/trunk/sound/pci/ice1712/ice1712.c @@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru return val != nval; } -static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Mixer To AC97", .info = snd_ice1712_digmix_route_ac97_info, @@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream, { unsigned int what = 0; unsigned int old; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ice->playback_pro_substream) { what |= ICE1712_PLAYBACK_START; snd_pcm_trigger_done(s, substream); @@ -1380,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); -static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Playback Switch", @@ -1404,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini }, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Multi Capture Switch", .info = snd_ice1712_pro_mixer_switch_info, @@ -1413,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d .private_value = 10, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), .info = snd_ice1712_pro_mixer_switch_info, @@ -1423,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de .count = 2, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -1435,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d .tlv = { .p = db_scale_playback } }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), .info = snd_ice1712_pro_mixer_volume_info, @@ -1627,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1712 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1663,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1714,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1723,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = .get = snd_ice1712_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1750,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), @@ -1891,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_ice1712_pro_internal_clock_info, @@ -1962,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock Default", .info = snd_ice1712_pro_internal_clock_default_info, @@ -2001,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_ice1712_pro_rate_locking_info, @@ -2040,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_ice1712_pro_rate_reset_info, @@ -2207,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_ice1712_pro_route_info, @@ -2215,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini .put = snd_ice1712_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_ice1712_pro_route_info, @@ -2257,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Volume Rate", .info = snd_ice1712_pro_volume_rate_info, @@ -2290,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -2305,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = /* * list of available boards */ -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_ice1712_hoontech_cards, snd_ice1712_delta_cards, snd_ice1712_ews_cards, @@ -2329,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, { int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2658,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; static int __devinit snd_ice1712_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) @@ -2667,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/trunk/sound/pci/ice1712/ice1712.h b/trunk/sound/pci/ice1712/ice1712.h index c3d9feaaf57d..6ac486d9c138 100644 --- a/trunk/sound/pci/ice1712/ice1712.h +++ b/trunk/sound/pci/ice1712/ice1712.h @@ -397,6 +397,9 @@ struct snd_ice1712 { struct ak4114 *ak4114; unsigned int analog: 1; } juli; + struct { + struct ak4114 *ak4114; + } prodigy192; } spec; }; diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 1127ebdf5fec..ee620dea7ef3 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); unsigned char what; unsigned char old; - struct list_head *pos; struct snd_pcm_substream *s; what = 0; - snd_pcm_group_for_each(pos, substream) { + snd_pcm_group_for_each_entry(s, substream) { const struct vt1724_pcm_reg *reg; - s = snd_pcm_group_substream_entry(pos); reg = s->runtime->private_data; what |= reg->start; snd_pcm_trigger_done(s, substream); @@ -1318,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1724 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1431,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, return (val != old); } -static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1463,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1472,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = .get = snd_vt1724_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1517,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol, return old != val; } -static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* FIXME: the following conflict with IEC958 Playback Route */ @@ -1668,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, spin_lock_irq(&ice->reg_lock); oval = inb(ICEMT1724(ice, RATE)); if (ucontrol->value.enumerated.item[0] == spdif) { + unsigned char i2s_oval; outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); + /* setting 256fs */ + i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); + outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, + ICEMT1724(ice, I2S_FORMAT)); } else { rate = rates[ucontrol->value.integer.value[0] % 15]; if (rate <= get_max_rate(ice)) { @@ -1695,7 +1698,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_vt1724_pro_internal_clock_info, @@ -1734,7 +1737,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_vt1724_pro_rate_locking_info, @@ -1773,7 +1776,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_vt1724_pro_rate_reset_info, @@ -1892,7 +1895,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, digital_route_shift(idx)); } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_vt1724_pro_route_info, @@ -1900,7 +1903,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit .put = snd_vt1724_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_vt1724_pro_route_info, @@ -1936,7 +1939,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -1948,9 +1951,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_revo_cards, snd_vt1724_amp_cards, snd_vt1724_aureon_cards, @@ -2009,7 +2012,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, { const int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2308,7 +2311,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -2347,6 +2350,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, } c = &no_matched; __found: + /* + * VT1724 has separate DMAs for the analog and the SPDIF streams while + * ICE1712 has only one for both (mixed up). + * + * Confusingly the analog PCM is named "professional" here because it + * was called so in ice1712 driver, and vt1724 driver is derived from + * ice1712 driver. + */ if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/ice1712/juli.c b/trunk/sound/pci/ice1712/juli.c index d88172fa95da..3d8e74e493d7 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 = { @@ -138,7 +138,16 @@ static const struct snd_akm4xxx akm_juli_dac __devinitdata = { static int __devinit juli_add_controls(struct snd_ice1712 *ice) { - return snd_ice1712_akm4xxx_build_controls(ice); + int err; + err = snd_ice1712_akm4xxx_build_controls(ice); + if (err < 0) + return err; + /* only capture SPDIF over AK4114 */ + err = snd_ak4114_build(ice->spec.juli.ak4114, NULL, + ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream); + if (err < 0) + return err; + return 0; } /* @@ -160,13 +169,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice) int err; struct snd_akm4xxx *ak; -#if 0 - for (err = 0; err < 0x20; err++) - juli_ak4114_read(ice, err); - juli_ak4114_write(ice, 0, 0x0f); - juli_ak4114_read(ice, 0); - juli_ak4114_read(ice, 1); -#endif err = snd_ak4114_create(ice->card, juli_ak4114_read, juli_ak4114_write, @@ -206,7 +208,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char juli_eeprom[] __devinitdata = { +static unsigned char juli_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -223,7 +225,7 @@ static const unsigned char juli_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_JULI, .name = "ESI Juli@", 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..40a9098af777 100644 --- a/trunk/sound/pci/ice1712/phase.c +++ b/trunk/sound/pci/ice1712/phase.c @@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = { #define WM_VOL_MAX (sizeof(wm_vol) - 1) #define WM_VOL_MUTE 0x8000 -static const struct snd_akm4xxx akm_phase22 __devinitdata = { +static struct snd_akm4xxx akm_phase22 __devinitdata = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, }; -static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { +static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { .caddr = 2, .cif = 1, .data_mask = 1 << 4, @@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) return 0; } -static const unsigned char phase22_eeprom[] __devinitdata = { +static unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ @@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char phase28_eeprom[] __devinitdata = { +static unsigned char phase28_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); -static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice) return 0; } -const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PHASE22, .name = "Terratec PHASE 22", 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..01c69453ddeb 100644 --- a/trunk/sound/pci/ice1712/pontis.c +++ b/trunk/sound/pci/ice1712/pontis.c @@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); * mixers */ -static const struct snd_kcontrol_new pontis_controls[] __devinitdata = { +static struct snd_kcontrol_new pontis_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char pontis_eeprom[] __devinitdata = { +static unsigned char pontis_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, .name = "Pontis MS300", 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..f03c02c07743 100644 --- a/trunk/sound/pci/ice1712/prodigy192.c +++ b/trunk/sound/pci/ice1712/prodigy192.c @@ -2,6 +2,37 @@ * ALSA driver for ICEnsemble VT1724 (Envy24HT) * * Lowlevel functions for AudioTrak Prodigy 192 cards + * Supported IEC958 input from optional MI/ODI/O add-on card. + * + * Specifics (SW, HW): + * ------------------- + * * 49.5MHz crystal + * * SPDIF-OUT on the card: + * - coax (through isolation transformer)/toslink supplied by + * 74HC04 gates - 3 in parallel + * - output switched between on-board CD drive dig-out connector + * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled + * by GPIO20 (0 = CD dig-out, 1 = SPDTX) + * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax + * + * * MI/ODI/O card: AK4114 based, used for iec958 input only + * - toslink input -> RX0 + * - coax input -> RX1 + * - 4wire protocol: + * AK4114 ICE1724 + * ------------------------------ + * CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + * - output data Mode 7 (24bit, I2S, slave) + * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which + * outputs master clock to SPMCLKIN of ice1724. + * Experimentally I found out that only a combination of + * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 - + * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct + * sampling rate. That means the the FPGA doubles the + * MCK01 rate. * * Copyright (c) 2003 Takashi Iwai * Copyright (c) 2003 Dimitromanolakis Apostolos @@ -356,6 +387,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } #endif +static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Line In", "Mic" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + + return 0; +} + + +static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; + return 0; +} + +static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old; + int change; + old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); + change = (new != old); + if (change) + stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); + return change; +} static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); @@ -364,7 +436,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); * mixers */ -static const struct snd_kcontrol_new stac_controls[] __devinitdata = { +static struct snd_kcontrol_new stac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -406,7 +478,7 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Switch", + .name = "ADC Capture Switch", .count = 1, .info = stac9460_adc_mute_info, .get = stac9460_adc_mute_get, @@ -417,13 +489,21 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "ADC Volume", + .name = "ADC Capture Volume", .count = 1, .info = stac9460_adc_vol_info, .get = stac9460_adc_vol_get, .put = stac9460_adc_vol_put, .tlv = { .p = db_scale_adc } }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Capture Input", + .info = stac9460_mic_sw_info, + .get = stac9460_mic_sw_get, + .put = stac9460_mic_sw_put, + + }, #if 0 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -456,19 +536,261 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { #endif }; + +/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ +/* CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + */ +#define AK4114_ADDR 0x00 /* C1-C0: Chip Address + * (According to datasheet fixed to “00”) + */ + +/* + * 4wire ak4114 protocol - writing data + */ +static void write_data(struct snd_ice1712 *ice, unsigned int gpio, + unsigned int data, int idx) +{ + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* set data */ + if (data & (1 << idx)) + gpio |= VT1724_PRODIGY192_CDOUT; + else + gpio &= ~VT1724_PRODIGY192_CDOUT; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } +} + +/* + * 4wire ak4114 protocol - reading data + */ +static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, + int idx) +{ + unsigned char data = 0; + + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* read data */ + if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) + data |= (1 << idx); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } + return data; +} +/* + * 4wire ak4114 protocol - starting sequence + */ +static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) +{ + unsigned int tmp; + + snd_ice1712_save_gpio_status(ice); + tmp = snd_ice1712_gpio_read(ice); + + tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ + tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + return tmp; +} + +/* + * 4wire ak4114 protocol - final sequence + */ +static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) +{ + tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + snd_ice1712_restore_gpio_status(ice); +} + +/* + * Write data to addr register of ak4114 + */ +static void prodigy192_ak4114_write(void *private_data, unsigned char addr, + unsigned char data) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp, addrdata; + tmp = prodigy192_4wire_start(ice); + addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); + addrdata = (addrdata << 8) | data; + write_data(ice, tmp, addrdata, 15); + prodigy192_4wire_finish(ice, tmp); +} + +/* + * Read data from addr register of ak4114 + */ +static unsigned char prodigy192_ak4114_read(void *private_data, + unsigned char addr) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp; + unsigned char data; + + tmp = prodigy192_4wire_start(ice); + write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); + data = read_data(ice, tmp, 7); + prodigy192_4wire_finish(ice, tmp); + return data; +} + + +static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Toslink", "Coax" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 bit = 0 -> RX0 = Toslink + * AK4114_IPS0 bit = 1 -> RX1 = Coax + */ + ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; + return 0; +} + +static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old, itemvalue; + int change; + + old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 could be any bit */ + itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; + + new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); + change = (new != old); + if (change) + prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); + return change; +} + + +static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "MIODIO IEC958 Capture Input", + .info = ak4114_input_sw_info, + .get = ak4114_input_sw_get, + .put = ak4114_input_sw_put, + + } +}; + + +static int prodigy192_ak4114_init(struct snd_ice1712 *ice) +{ + static const unsigned char ak4114_init_vals[] = { + AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, + /* ice1724 expects I2S and provides clock, + * DEM0 disables the deemphasis filter + */ + AK4114_DIF_I24I2S | AK4114_DEM0 , + AK4114_TX1E, + AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ + 0, + 0 + }; + static const unsigned char ak4114_init_txcsb[] = { + 0x41, 0x02, 0x2c, 0x00, 0x00 + }; + + return snd_ak4114_create(ice->card, + prodigy192_ak4114_read, + prodigy192_ak4114_write, + ak4114_init_vals, ak4114_init_txcsb, + ice, &ice->spec.prodigy192.ak4114); +} + static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) { unsigned int i; int err; for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice)); + err = snd_ctl_add(ice->card, + snd_ctl_new1(&stac_controls[i], ice)); + if (err < 0) + return err; + } + if (ice->spec.prodigy192.ak4114) { + /* ak4114 is connected */ + for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { + err = snd_ctl_add(ice->card, + snd_ctl_new1(&ak4114_controls[i], + ice)); + if (err < 0) + return err; + } + err = snd_ak4114_build(ice->spec.prodigy192.ak4114, + NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ + ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); if (err < 0) return err; } return 0; } +/* + * check for presence of MI/ODI/O add-on card with digital inputs + */ +static int prodigy192_miodio_exists(struct snd_ice1712 *ice) +{ + + unsigned char orig_value; + const unsigned char test_data = 0xd1; /* random value */ + unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ + int exists = 0; + + orig_value = prodigy192_ak4114_read(ice, addr); + prodigy192_ak4114_write(ice, addr, test_data); + if (prodigy192_ak4114_read(ice, addr) == test_data) { + /* ak4114 seems to communicate, apparently exists */ + /* writing back original value */ + prodigy192_ak4114_write(ice, addr, orig_value); + exists = 1; + } + return exists; +} /* * initialize the chip @@ -487,16 +809,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) (unsigned short)-1 }; const unsigned short *p; + int err = 0; /* prodigy 192 */ ice->num_total_dacs = 6; ice->num_total_adcs = 2; + ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ /* initialize codec */ p = stac_inits_prodigy; for (; *p != (unsigned short)-1; p += 2) stac9460_put(ice, p[0], p[1]); + /* MI/ODI/O add on card with AK4114 */ + if (prodigy192_miodio_exists(ice)) { + err = prodigy192_ak4114_init(ice); + /* from this moment if err = 0 then + * ice->spec.prodigy192.ak4114 should not be null + */ + snd_printdd("AK4114 initialized with status %d\n", err); + } else + snd_printdd("AK4114 not found\n"); + if (err < 0) + return err; + return 0; } @@ -506,25 +842,31 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char prodigy71_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ +static unsigned char prodigy71_eeprom[] __devinitdata = { + [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, + * spdif-in+ 1 stereo ADC, + * 3 stereo DACs + */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, + [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , [ICE_EEP2_GPIO_DIR2] = 0xbf, [ICE_EEP2_GPIO_MASK] = 0x00, [ICE_EEP2_GPIO_MASK1] = 0x00, [ICE_EEP2_GPIO_MASK2] = 0x00, [ICE_EEP2_GPIO_STATE] = 0x00, [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, + [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input + * passthrough, + * 1 = SPDIF-OUT from ice1724 + */ }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, .name = "Audiotrak Prodigy 192", diff --git a/trunk/sound/pci/ice1712/prodigy192.h b/trunk/sound/pci/ice1712/prodigy192.h index 2fa2e62b9e04..16a53b459c72 100644 --- a/trunk/sound/pci/ice1712/prodigy192.h +++ b/trunk/sound/pci/ice1712/prodigy192.h @@ -5,7 +5,15 @@ #define PRODIGY192_STAC9460_ADDR 0x54 #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ +/* + * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with + * AK4114 (SPDIF-IN) + */ +#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */ +#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */ +#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */ +#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */ -extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; #endif /* __SOUND_PRODIGY192_H */ diff --git a/trunk/sound/pci/ice1712/revo.c b/trunk/sound/pci/ice1712/revo.c index 025a7e8497c3..690ceb340644 100644 --- a/trunk/sound/pci/ice1712/revo.c +++ b/trunk/sound/pci/ice1712/revo.c @@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static const struct snd_akm4xxx akm_revo_front __devinitdata = { +static struct snd_akm4xxx akm_revo_front __devinitdata = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = { .dac_info = revo71_front, }; -static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo_surround __devinitdata = { +static struct snd_akm4xxx akm_revo_surround __devinitdata = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = { .dac_info = revo71_surround, }; -static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51 __devinitdata = { +static struct snd_akm4xxx akm_revo51 __devinitdata = { .type = SND_AK4358, .num_dacs = 6, .ops = { @@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = { .dac_info = revo51_dac, }; -static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51_adc __devinitdata = { +static struct snd_akm4xxx akm_revo51_adc __devinitdata = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { AK_DAC("PCM Playback Volume", 2) }; -static const struct snd_akm4xxx akm_ap192 __devinitdata = { +static struct snd_akm4xxx akm_ap192 __devinitdata = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = { .dac_info = ap192_dac, }; -static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, return data; } -static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) +static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) { unsigned int tmp; @@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) return data; } -static int ap192_ak4114_init(struct snd_ice1712 *ice) +static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, @@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) } /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_REVOLUTION71, .name = "M Audio Revolution-7.1", diff --git a/trunk/sound/pci/ice1712/revo.h b/trunk/sound/pci/ice1712/revo.h index 2a24488fad80..a3ba425911cc 100644 --- a/trunk/sound/pci/ice1712/revo.h +++ b/trunk/sound/pci/ice1712/revo.h @@ -34,7 +34,7 @@ #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 /* entry point */ -extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; /* diff --git a/trunk/sound/pci/ice1712/vt1720_mobo.c b/trunk/sound/pci/ice1712/vt1720_mobo.c index 72b060d63c29..239524158fe7 100644 --- a/trunk/sound/pci/ice1712/vt1720_mobo.c +++ b/trunk/sound/pci/ice1712/vt1720_mobo.c @@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) /* EEPROM image */ -static const unsigned char k8x800_eeprom[] __devinitdata = { +static unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ }; -static const unsigned char sn25p_eeprom[] __devinitdata = { +static unsigned char sn25p_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = { /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_K8X800, .name = "Albatron K8X800 Pro II", 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 index 4a706b16a0b9..04e535c8542b 100644 --- a/trunk/sound/pci/ice1712/wtm.c +++ b/trunk/sound/pci/ice1712/wtm.c @@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, /* * Control tabs */ -static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = { +static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 7cf2dcb9d8d4..202f720b34b9 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci) return -EIO; } pci_set_master(pci); + snd_intel8x0_chip_init(chip, 0); if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED, card->shortname, chip)) { printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " @@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci) } chip->irq = pci->irq; synchronize_irq(chip->irq); - snd_intel8x0_chip_init(chip, 0); /* re-initialize mixer stuff */ if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { @@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; chip->int_sta_mask = int_sta_masks; - /* request irq after initializaing int_sta_mask, etc */ - if (request_irq(pci->irq, snd_intel8x0_interrupt, - IRQF_SHARED, card->shortname, chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_intel8x0_free(chip); - return -EBUSY; - } - chip->irq = pci->irq; pci_set_master(pci); - synchronize_irq(chip->irq); switch(chip->device_type) { case DEVICE_INTEL_ICH4: @@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, return err; } + /* request irq after initializaing int_sta_mask, etc */ + if (request_irq(pci->irq, snd_intel8x0_interrupt, + IRQF_SHARED, card->shortname, chip)) { + snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_intel8x0_free(chip); + return -EBUSY; + } + chip->irq = pci->irq; + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_intel8x0_free(chip); return err; diff --git a/trunk/sound/pci/korg1212/korg1212.c b/trunk/sound/pci/korg1212/korg1212.c index 21d0899ac382..5338243fb035 100644 --- a/trunk/sound/pci/korg1212/korg1212.c +++ b/trunk/sound/pci/korg1212/korg1212.c @@ -264,9 +264,7 @@ enum MonitorModeSelector { #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command. -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL #include "korg1212-firmware.h" static const struct firmware static_dsp_code = { .data = (u8 *)dspCode, @@ -418,6 +416,9 @@ struct snd_korg1212 { MODULE_DESCRIPTION("korg1212"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("korg/k1212.dsp"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2342,26 +2343,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, AdatTimeCode); +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + dsp_code = &static_dsp_code; +#else err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); -#ifdef FIRMWARE_IN_THE_KERNEL - dsp_code = &static_dsp_code; -#else snd_printk(KERN_ERR "firmware not available\n"); snd_korg1212_free(korg1212); return err; -#endif } +#endif if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), dsp_code->size, &korg1212->dma_dsp) < 0) { snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); snd_korg1212_free(korg1212); -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); return -ENOMEM; } @@ -2371,10 +2371,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 4526904e3f86..8a5ff1cb5362 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," "{ESS,Canyon3D-2/LE PCI}}"); +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw"); +MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2101,9 +2105,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL /* * DSP Code images @@ -2242,7 +2244,7 @@ static const struct firmware assp_minisrc = { .size = sizeof assp_minisrc_image }; -#endif /* FIRMWARE_IN_THE_KERNEL */ +#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ #ifdef __LITTLE_ENDIAN static inline void snd_m3_convert_from_le(const struct firmware *fw) { } @@ -2257,6 +2259,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw) } #endif +#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ + /* * initialize ASSP @@ -2550,14 +2554,10 @@ static int snd_m3_free(struct snd_m3 *chip) if (chip->iobase) pci_release_regions(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->assp_kernel_image != &assp_kernel) +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + release_firmware(chip->assp_kernel_image); + release_firmware(chip->assp_minisrc_image); #endif - release_firmware(chip->assp_kernel_image); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->assp_minisrc_image != &assp_minisrc) -#endif - release_firmware(chip->assp_minisrc_image); pci_disable_device(chip->pci); kfree(chip); @@ -2747,29 +2747,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -ENOMEM; } +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_kernel_image = &assp_kernel; +#else err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->assp_kernel_image = &assp_kernel; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_kernel_image); +#endif +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_minisrc_image = &assp_minisrc; +#else err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->assp_minisrc_image = &assp_minisrc; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_minisrc_image); +#endif if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); diff --git a/trunk/sound/pci/mixart/mixart_hwdep.c b/trunk/sound/pci/mixart/mixart_hwdep.c index ca05075c67c6..1d9232d2db34 100644 --- a/trunk/sound/pci/mixart/mixart_hwdep.c +++ b/trunk/sound/pci/mixart/mixart_hwdep.c @@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr) return 0; } +MODULE_FIRMWARE("mixart/miXart8.xlx"); +MODULE_FIRMWARE("mixart/miXart8.elf"); +MODULE_FIRMWARE("mixart/miXart8AES.xlx"); #else /* old style firmware loading */ diff --git a/trunk/sound/pci/pcxhr/pcxhr.c b/trunk/sound/pci/pcxhr/pcxhr.c index d97413484ae9..f7f6a687f033 100644 --- a/trunk/sound/pci/pcxhr/pcxhr.c +++ b/trunk/sound/pci/pcxhr/pcxhr.c @@ -638,22 +638,22 @@ static void pcxhr_trigger_tasklet(unsigned long arg) static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) { struct pcxhr_stream *stream; - struct list_head *pos; struct snd_pcm_substream *s; - int i; switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_printdd("SNDRV_PCM_TRIGGER_START\n"); - i = 0; - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); - stream = s->runtime->private_data; - stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; - snd_pcm_trigger_done(s, subs); - i++; - } - if (i==1) { + if (snd_pcm_stream_linked(subs)) { + struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); + snd_pcm_group_for_each_entry(s, subs) { + stream = s->runtime->private_data; + stream->status = + PCXHR_STREAM_STATUS_SCHEDULE_RUN; + snd_pcm_trigger_done(s, subs); + } + tasklet_hi_schedule(&chip->mgr->trigger_taskq); + } else { + stream = subs->runtime->private_data; snd_printdd("Only one Substream %c %d\n", stream->pipe->is_capture ? 'C' : 'P', stream->pipe->first_audio); @@ -665,15 +665,11 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) if (pcxhr_set_stream_state(stream)) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_RUNNING; - } else { - struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); - tasklet_hi_schedule(&chip->mgr->trigger_taskq); } break; case SNDRV_PCM_TRIGGER_STOP: snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, subs) { stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; if (pcxhr_set_stream_state(stream)) diff --git a/trunk/sound/pci/pcxhr/pcxhr_hwdep.c b/trunk/sound/pci/pcxhr/pcxhr_hwdep.c index 369c19fea985..d55d8bc90eee 100644 --- a/trunk/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/trunk/sound/pci/pcxhr/pcxhr_hwdep.c @@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) return 0; } +MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); +MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); +MODULE_FIRMWARE("pcxhr/e321_512.e56"); +MODULE_FIRMWARE("pcxhr/b321_512.b56"); +MODULE_FIRMWARE("pcxhr/d321_512.d56"); + #else /* old style firmware loading */ /* pcxhr hwdep interface id string */ diff --git a/trunk/sound/pci/riptide/riptide.c b/trunk/sound/pci/riptide/riptide.c index 952625dead58..8e5410483e67 100644 --- a/trunk/sound/pci/riptide/riptide.c +++ b/trunk/sound/pci/riptide/riptide.c @@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber "); MODULE_DESCRIPTION("riptide"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); +MODULE_FIRMWARE("riptide.hex"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; diff --git a/trunk/sound/pci/rme32.c b/trunk/sound/pci/rme32.c index 6bb7ac650ec4..618653e22561 100644 --- a/trunk/sound/pci/rme32.c +++ b/trunk/sound/pci/rme32.c @@ -1078,12 +1078,10 @@ static int snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct rme32 *rme32 = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; spin_lock(&rme32->lock); - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s != rme32->playback_substream && s != rme32->capture_substream) continue; @@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) /* prefill playback buffer */ if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == rme32->playback_substream) { s->ops->ack(s); break; diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index 89b3c7ff5037..3b3ef657f73e 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -60,6 +60,12 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); +#ifdef HDSP_FW_LOADER +MODULE_FIRMWARE("multiface_firmware.bin"); +MODULE_FIRMWARE("multiface_firmware_rev11.bin"); +MODULE_FIRMWARE("digiface_firmware.bin"); +MODULE_FIRMWARE("digiface_firmware_rev11.bin"); +#endif #define HDSP_MAX_CHANNELS 26 #define HDSP_MAX_DS_CHANNELS 14 @@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) +/* RME says n = 104857600000000, but in the windows MADI driver, I see: + return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz +*/ +#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */ #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) @@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) else if (rate >= 56000) rate /= 2; - /* RME says n = 104857600000000, but in the windows MADI driver, I see: -// return 104857600000000 / rate; // 100 MHz - return 110100480000000 / rate; // 105 MHz - */ - n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = DDS_NUMERATOR; div64_32(&n, rate, &r); /* n should be less than 2^32 for being written to FREQ register */ snd_assert((n >> 32) == 0); @@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn return 0; } +#define HDSP_DDS_OFFSET(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdsp_info_dds_offset, \ + .get = snd_hdsp_get_dds_offset, \ + .put = snd_hdsp_put_dds_offset \ +} + +static int hdsp_dds_offset(struct hdsp *hdsp) +{ + u64 n; + u32 r; + unsigned int dds_value = hdsp->dds_value; + int system_sample_rate = hdsp->system_sample_rate; + + n = DDS_NUMERATOR; + /* + * dds_value = n / rate + * rate = n / dds_value + */ + div64_32(&n, dds_value, &r); + if (system_sample_rate >= 112000) + n *= 4; + else if (system_sample_rate >= 56000) + n *= 2; + return ((int)n) - system_sample_rate; +} + +static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz) +{ + int rate = hdsp->system_sample_rate + offset_hz; + hdsp_set_dds_value(hdsp, rate); + return 0; +} + +static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = -5000; + uinfo->value.integer.max = 5000; + return 0; +} + +static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); + return 0; +} + +static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_dds_offset(hdsp)) + change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { HDSP_DA_GAIN("DA Gain", 0), HDSP_AD_GAIN("AD Gain", 0), HDSP_PHONE_GAIN("Phones Gain", 0), -HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0) +HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), +HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) }; static struct snd_kcontrol_new snd_hdsp_controls[] = { @@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd) other = hdsp->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 6e95857e4e67..143185e7e4dc 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_controlRegister 64 #define HDSPM_interruptConfirmation 96 #define HDSPM_control2Reg 256 /* not in specs ???????? */ +#define HDSPM_freqReg 256 /* for AES32 */ #define HDSPM_midiDataOut0 352 /* just believe in old code */ #define HDSPM_midiDataOut1 356 +#define HDSPM_eeprom_wr 384 /* for AES32 */ /* DMA enable for 64 channels, only Bit 0 is relevant */ #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ @@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); size is the same regardless of the number of channels, and also the latency to use. for one direction !!! - => need to mupltiply by 2!! */ -#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) +#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) /* revisions >= 230 indicate AES32 card */ @@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { 56, 57, 58, 59, 60, 61, 62, 63 }; -static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = { - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60 - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - static struct pci_device_id snd_hdspm_ids[] __devinitdata = { { @@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) return 0; } +static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) +{ + u64 n; + u32 r; + + if (rate >= 112000) + rate /= 4; + else if (rate >= 56000) + rate /= 2; + + /* RME says n = 104857600000000, but in the windows MADI driver, I see: +// return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz + */ + //n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = 110100480000000ULL; /* Value checked for AES32 and MADI */ + div64_32(&n, rate, &r); + /* n should be less than 2^32 for being written to FREQ register */ + snd_assert((n >> 32) == 0); + hdspm_write(hdspm, HDSPM_freqReg, (u32)n); +} /* dummy set rate lets see what happens */ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) @@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) hdspm->control_register |= rate_bits; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - if (rate > 96000 /* 64000*/) - hdspm->channel_map = channel_map_madi_qs; - else if (rate > 48000) - hdspm->channel_map = channel_map_madi_ds; - else - hdspm->channel_map = channel_map_madi_ss; + /* For AES32, need to set DDS value in FREQ register + For MADI, also apparently */ + hdspm_set_dds_value(hdspm, rate); + + if (hdspm->is_aes32 && rate != current_rate) + hdspm_write(hdspm, HDSPM_eeprom_wr, 0); + + /* For AES32 and for MADI (at least rev 204), channel_map needs to + * always be channel_map_madi_ss, whatever the sample rate */ + hdspm->channel_map = channel_map_madi_ss; hdspm->system_sample_rate = rate; @@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); snd_iprintf(buffer, - "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", - hdspm->control_register, hdspm->control2_register, + "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", + hdspm->control_register, status, status2, timecode); snd_iprintf(buffer, "--- Settings ---\n"); @@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); + if (!hdspm->is_aes32) { + /* No control2 register for AES32 */ #ifdef SNDRV_BIG_ENDIAN - hdspm->control2_register = HDSPM_BIGENDIAN_MODE; + hdspm->control2_register = HDSPM_BIGENDIAN_MODE; #else - hdspm->control2_register = 0; + hdspm->control2_register = 0; #endif - hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + } hdspm_compute_period_size(hdspm); /* silence everything */ @@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; @@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, /* Memory allocation, takashi's method, dont know if we should spinlock */ /* malloc all buffer even if not enabled to get sure */ - /* malloc only needed bytes */ + /* Update for MADI rev 204: we need to allocate for all channels, + * otherwise it doesn't work at 96kHz */ err = - snd_pcm_lib_malloc_pages(substream, - HDSPM_CHANNEL_BUFFER_BYTES * - params_channels(params)); + snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); if (err < 0) return err; @@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, "playback" : "capture", snd_pcm_sgbuf_get_addr(sgbuf, 0)); */ + /* + snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + "playback" : "capture", + params_rate(params), params_channels(params), + params_buffer_size(params)); + */ return 0; } @@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) other = hdspm->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) @@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (r->min > 48000) { + if (r->min > 48000 && r->max <= 96000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ds_channels, .max = hdspm->ds_channels, .integer = 1, }; return snd_interval_refine(c, &t); } else if (r->max < 64000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ss_channels, .max = hdspm->ss_channels, .integer = 1, }; @@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (c->min <= hdspm->ss_channels) { + if (c->min >= hdspm->ss_channels) { struct snd_interval t = { .min = 32000, .max = 48000, .integer = 1, }; return snd_interval_refine(r, &t); - } else if (c->max > hdspm->ss_channels) { + } else if (c->max <= hdspm->ds_channels) { struct snd_interval t = { .min = 64000, .max = 96000, @@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, return 0; } +static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + unsigned int list[3]; + struct hdspm *hdspm = rule->private; + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + if (hdspm->is_aes32) { + list[0] = hdspm->qs_channels; + list[1] = hdspm->ds_channels; + list[2] = hdspm->ss_channels; + return snd_interval_list(c, 3, list, 0); + } else { + list[0] = hdspm->ds_channels; + list[1] = hdspm->ss_channels; + return snd_interval_list(c, 2, list, 0); + } +} + + +static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; + +static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { + .count = ARRAY_SIZE(hdspm_aes32_sample_rates), + .list = hdspm_aes32_sample_rates, + .mask = 0 +}; + static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) { struct hdspm *hdspm = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_printdd("Open device substream %d\n", substream->stream); - spin_lock_irq(&hdspm->lock); snd_pcm_set_sync(substream); @@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } @@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index cc3bdececce7..bd7dbd267ed1 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream, other = rme9652->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/trunk/sound/pci/trident/trident_main.c b/trunk/sound/pci/trident/trident_main.c index 3bff32167f66..7ca606272460 100644 --- a/trunk/sound/pci/trident/trident_main.c +++ b/trunk/sound/pci/trident/trident_main.c @@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, { struct snd_trident *trident = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag, spdif_flag; struct snd_trident_voice *voice, *evoice; @@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, what = whati = capture_flag = spdif_flag = 0; spin_lock(&trident->reg_lock); val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { voice = s->runtime->private_data; evoice = voice->extra; diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index fd12674d0394..ea861bceaddf 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) } } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL #include "ymfpci_image.h" @@ -2018,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = { }; #endif +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL +static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) +{ + chip->dsp_microcode = &snd_ymfpci_dsp_microcode; + if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || + chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || + chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || + chip->device_id == PCI_DEVICE_ID_YAMAHA_754) + chip->controller_microcode = + &snd_ymfpci_controller_1e_microcode; + else + chip->controller_microcode = + &snd_ymfpci_controller_microcode; + return 0; +} + +#else /* use fw_loader */ + #ifdef __LITTLE_ENDIAN static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } #else @@ -2046,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->dsp_microcode = &snd_ymfpci_dsp_microcode; -#else + if (err < 0) return err; -#endif - } is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || @@ -2069,18 +2080,17 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->controller_microcode = - is_1e ? &snd_ymfpci_controller_1e_microcode - : &snd_ymfpci_controller_microcode; -#else + if (err < 0) return err; -#endif - } return 0; } +MODULE_FIRMWARE("yamaha/ds1_dsp.fw"); +MODULE_FIRMWARE("yamaha/ds1_ctrl.fw"); +MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw"); + +#endif + static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { int i; @@ -2259,15 +2269,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); pci_disable_device(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode) -#endif - release_firmware(chip->dsp_microcode); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->controller_microcode != &snd_ymfpci_controller_microcode && - chip->controller_microcode != &snd_ymfpci_controller_1e_microcode) +#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL + release_firmware(chip->dsp_microcode); + release_firmware(chip->controller_microcode); #endif - release_firmware(chip->controller_microcode); kfree(chip); return 0; } diff --git a/trunk/sound/pcmcia/vx/vxpocket.c b/trunk/sound/pcmcia/vx/vxpocket.c index 363bcb5f08e6..c57e127d9ccb 100644 --- a/trunk/sound/pcmcia/vx/vxpocket.c +++ b/trunk/sound/pcmcia/vx/vxpocket.c @@ -297,7 +297,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) /* find an empty slot from the card list */ for (i = 0; i < SNDRV_CARDS; i++) { - if (! card_alloc & (1 << i)) + if (!(card_alloc & (1 << i))) break; } if (i >= SNDRV_CARDS) { diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig index dccaa4be679e..10cffc087181 100644 --- a/trunk/sound/soc/Kconfig +++ b/trunk/sound/soc/Kconfig @@ -2,31 +2,31 @@ # SoC audio configuration # -menu "SoC audio support" +menu "System on Chip audio support" depends on SND!=n config SND_SOC_AC97_BUS bool config SND_SOC - tristate "SoC audio support" + tristate "ALSA for SoC audio support" depends on SND select SND_PCM ---help--- - If you want SoC support, you should say Y here and also to the - specific driver for your SoC below. You will also need to select the - specific codec(s) attached to the SoC + If you want ASoC support, you should say Y here and also to the + specific driver for your SoC platform below. + + ASoC provides power efficient ALSA support for embedded battery powered + SoC based systems like PDA's, Phones and Personal Media Players. - This SoC audio support can also be built as a module. If so, the module + This ASoC audio support can also be built as a module. If so, the module will be called snd-soc-core. # All the supported Soc's -menu "SoC Platforms" -depends on SND_SOC source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" -endmenu +source "sound/soc/s3c24xx/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile index 98e6f49dafc2..0ae2e49036f9 100644 --- a/trunk/sound/soc/Makefile +++ b/trunk/sound/soc/Makefile @@ -1,4 +1,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o -obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ +obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ diff --git a/trunk/sound/soc/at91/Kconfig b/trunk/sound/soc/at91/Kconfig index a5b2558916c1..5cb93fd3a407 100644 --- a/trunk/sound/soc/at91/Kconfig +++ b/trunk/sound/soc/at91/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Atmel AT91" - config SND_AT91_SOC tristate "SoC Audio for the Atmel AT91 System-on-Chip" depends on ARCH_AT91 && SND_SOC @@ -8,13 +6,13 @@ config SND_AT91_SOC the AT91 SSC interface. You will also need to select the audio interfaces to support below. -config SND_AT91_SOC_I2S +config SND_AT91_SOC_SSC tristate config SND_AT91_SOC_ETI_B1_WM8731 - tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards" + tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards" depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) - select SND_AT91_SOC_I2S + select SND_AT91_SOC_SSC select SND_SOC_WM8731 help Say Y if you want to add support for SoC audio on WM8731-based @@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE help Say Y if you want to run with the AT91 SSC generating the BCLK and LRC signals on Endrelia boards. - -endmenu diff --git a/trunk/sound/soc/at91/Makefile b/trunk/sound/soc/at91/Makefile index b77b01ab2028..f23da17cc328 100644 --- a/trunk/sound/soc/at91/Makefile +++ b/trunk/sound/soc/at91/Makefile @@ -1,9 +1,9 @@ # AT91 Platform Support snd-soc-at91-objs := at91-pcm.o -snd-soc-at91-i2s-objs := at91-i2s.o +snd-soc-at91-ssc-objs := at91-ssc.o obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o -obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o +obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o # AT91 Machine Support snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o diff --git a/trunk/sound/soc/at91/at91-i2s.c b/trunk/sound/soc/at91/at91-ssc.c similarity index 73% rename from trunk/sound/soc/at91/at91-i2s.c rename to trunk/sound/soc/at91/at91-ssc.c index 9fc0c0388881..3d4e32cff75e 100644 --- a/trunk/sound/soc/at91/at91-i2s.c +++ b/trunk/sound/soc/at91/at91-ssc.c @@ -1,5 +1,5 @@ /* - * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver + * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver * * Author: Frank Mandarino * Endrelia Technologies Inc. @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -33,10 +34,10 @@ #include #include "at91-pcm.h" -#include "at91-i2s.h" +#include "at91-ssc.h" #if 0 -#define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x) +#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x) #else #define DBG(x...) #endif @@ -92,33 +93,33 @@ static struct at91_ssc_mask ssc_rx_mask = { */ static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { {{ - .name = "SSC0/I2S PCM Stereo out", + .name = "SSC0 PCM out", .pdc = &pdc_tx_reg, .mask = &ssc_tx_mask, }, { - .name = "SSC0/I2S PCM Stereo in", + .name = "SSC0 PCM in", .pdc = &pdc_rx_reg, .mask = &ssc_rx_mask, }}, #if NUM_SSC_DEVICES == 3 {{ - .name = "SSC1/I2S PCM Stereo out", + .name = "SSC1 PCM out", .pdc = &pdc_tx_reg, .mask = &ssc_tx_mask, }, { - .name = "SSC1/I2S PCM Stereo in", + .name = "SSC1 PCM in", .pdc = &pdc_rx_reg, .mask = &ssc_rx_mask, }}, {{ - .name = "SSC2/I2S PCM Stereo out", + .name = "SSC2 PCM out", .pdc = &pdc_tx_reg, .mask = &ssc_tx_mask, }, { - .name = "SSC1/I2S PCM Stereo in", + .name = "SSC2 PCM in", .pdc = &pdc_rx_reg, .mask = &ssc_rx_mask, }}, @@ -151,33 +152,33 @@ static struct at91_ssc_info { } ssc_info[NUM_SSC_DEVICES] = { { .name = "ssc0", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock), .dir_mask = 0, .initialized = 0, }, #if NUM_SSC_DEVICES == 3 { .name = "ssc1", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), .dir_mask = 0, .initialized = 0, }, { .name = "ssc2", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock), .dir_mask = 0, .initialized = 0, }, #endif }; -static unsigned int at91_i2s_sysclk; +static unsigned int at91_ssc_sysclk; /* * SSC interrupt handler. Passes PDC interrupts to the DMA * interrupt handler in the PCM driver. */ -static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) +static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id) { struct at91_ssc_info *ssc_p = dev_id; struct at91_pcm_dma_params *dma_params; @@ -209,13 +210,13 @@ static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) /* * Startup. Only that one substream allowed in each direction. */ -static int at91_i2s_startup(struct snd_pcm_substream *substream) +static int at91_ssc_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; int dir_mask; - DBG("i2s_startup: SSC_SR=0x%08lx\n", + DBG("ssc_startup: SSC_SR=0x%08lx\n", at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; @@ -234,7 +235,7 @@ static int at91_i2s_startup(struct snd_pcm_substream *substream) * 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) +static void at91_ssc_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; @@ -281,7 +282,7 @@ static void at91_i2s_shutdown(struct snd_pcm_substream *substream) /* * Record the SSC system clock rate. */ -static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { /* @@ -291,7 +292,7 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, */ switch (clk_id) { case AT91_SYSCLK_MCK: - at91_i2s_sysclk = freq; + at91_ssc_sysclk = freq; break; default: return -EINVAL; @@ -303,14 +304,11 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, /* * Record the DAI format for use in hw_params(). */ -static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int fmt) { struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; - if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) - return -EINVAL; - ssc_p->daifmt = fmt; return 0; } @@ -318,7 +316,7 @@ static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, /* * Record SSC clock dividers for use in hw_params(). */ -static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, +static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, int div_id, int div) { struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; @@ -355,7 +353,7 @@ static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, /* * Configure the SSC. */ -static int at91_i2s_hw_params(struct snd_pcm_substream *substream, +static int at91_ssc_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -390,21 +388,51 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, channels = params_channels(params); + /* + * Determine sample size in bits and the PDC increment. + */ + switch(params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + bits = 8; + dma_params->pdc_xfer_size = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + bits = 16; + dma_params->pdc_xfer_size = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bits = 24; + dma_params->pdc_xfer_size = 4; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bits = 32; + dma_params->pdc_xfer_size = 4; + break; + default: + printk(KERN_WARNING "at91-ssc: unsupported PCM format"); + return -EINVAL; + } + /* * The SSC only supports up to 16-bit samples in I2S format, due - * to the size of the Frame Mode Register FSLEN field. Also, I2S - * implies signed data. + * to the size of the Frame Mode Register FSLEN field. */ - bits = 16; - dma_params->pdc_xfer_size = 2; + if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S + && bits > 16) { + printk(KERN_WARNING + "at91-ssc: sample size %d is too large for I2S\n", bits); + return -EINVAL; + } /* * Compute SSC register settings. */ - switch (ssc_p->daifmt) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (ssc_p->daifmt + & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { + + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: /* - * SSC provides BCLK and LRC clocks. + * I2S format, SSC provides BCLK and LRC clocks. * * The SSC transmit and receive clocks are generated from the * MCK divider, and the BCLK signal is output on the SSC TK line. @@ -441,10 +469,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | (((bits - 1) << 0) & AT91_SSC_DATALEN); break; - case SND_SOC_DAIFMT_CBM_CFM: - + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: /* - * CODEC supplies BCLK and LRC clocks. + * I2S format, CODEC supplies BCLK and LRC clocks. * * The SSC transmit clock is obtained from the BCLK signal on * on the TK line, and the SSC receive clock is generated from the @@ -490,10 +517,51 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, | (((bits - 1) << 0) & AT91_SSC_DATALEN); break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: + /* + * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. + * + * The SSC transmit and receive clocks are generated from the + * MCK divider, and the BCLK signal is output on the SSC TK line. + */ + rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_LOOP) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( 0 << 23) & AT91_SSC_FSDEN) + | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_DATDEF) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + + + break; + + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: default: - printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n", + printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n", ssc_p->daifmt); return -EINVAL; break; @@ -518,9 +586,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); - if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt, + if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt, 0, ssc_p->name, ssc_p)) < 0) { - printk(KERN_WARNING "at91-i2s: request_irq failure\n"); + printk(KERN_WARNING "at91-ssc: request_irq failure\n"); DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); @@ -546,7 +614,7 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream, } -static int at91_i2s_prepare(struct snd_pcm_substream *substream) +static int at91_ssc_prepare(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; @@ -566,7 +634,7 @@ static int at91_i2s_prepare(struct snd_pcm_substream *substream) #ifdef CONFIG_PM -static int at91_i2s_suspend(struct platform_device *pdev, +static int at91_ssc_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai) { struct at91_ssc_info *ssc_p; @@ -594,7 +662,7 @@ static int at91_i2s_suspend(struct platform_device *pdev, return 0; } -static int at91_i2s_resume(struct platform_device *pdev, +static int at91_ssc_resume(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai) { struct at91_ssc_info *ssc_p; @@ -620,102 +688,105 @@ static int at91_i2s_resume(struct platform_device *pdev, } #else -#define at91_i2s_suspend NULL -#define at91_i2s_resume NULL +#define at91_ssc_suspend NULL +#define at91_ssc_resume NULL #endif -#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ +#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ SNDRV_PCM_RATE_96000) -struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = { - { .name = "at91_ssc0/i2s", +#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = { + { .name = "at91-ssc0", .id = 0, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, .playback = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .capture = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_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,}, + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[0].ssc, }, #if NUM_SSC_DEVICES == 3 - { .name = "at91_ssc1/i2s", + { .name = "at91-ssc1", .id = 1, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, .playback = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .capture = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_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,}, + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[1].ssc, }, - { .name = "at91_ssc2/i2s", + { .name = "at91-ssc2", .id = 2, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, .playback = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .capture = { .channels_min = 1, .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_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,}, + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, .private_data = &ssc_info[2].ssc, }, #endif }; -EXPORT_SYMBOL_GPL(at91_i2s_dai); +EXPORT_SYMBOL_GPL(at91_ssc_dai); /* Module information */ MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); -MODULE_DESCRIPTION("AT91 I2S ASoC Interface"); +MODULE_DESCRIPTION("AT91 SSC ASoC Interface"); MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/at91/at91-i2s.h b/trunk/sound/soc/at91/at91-ssc.h similarity index 72% rename from trunk/sound/soc/at91/at91-i2s.h rename to trunk/sound/soc/at91/at91-ssc.h index f8a875ba0ccc..b188f973df9f 100644 --- a/trunk/sound/soc/at91/at91-i2s.h +++ b/trunk/sound/soc/at91/at91-ssc.h @@ -1,5 +1,5 @@ /* - * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC + * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC * * Author: Frank Mandarino * Endrelia Technologies Inc. @@ -10,18 +10,18 @@ * published by the Free Software Foundation. */ -#ifndef _AT91_I2S_H -#define _AT91_I2S_H +#ifndef _AT91_SSC_H +#define _AT91_SSC_H -/* I2S system clock ids */ +/* SSC system clock ids */ #define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ -/* I2S divider ids */ +/* SSC divider ids */ #define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ #define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ #define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ -extern struct snd_soc_cpu_dai at91_i2s_dai[]; +extern struct snd_soc_cpu_dai at91_ssc_dai[]; -#endif /* _AT91_I2S_H */ +#endif /* _AT91_SSC_H */ diff --git a/trunk/sound/soc/at91/eti_b1_wm8731.c b/trunk/sound/soc/at91/eti_b1_wm8731.c index 8179df3bb2f3..820a676c56bf 100644 --- a/trunk/sound/soc/at91/eti_b1_wm8731.c +++ b/trunk/sound/soc/at91/eti_b1_wm8731.c @@ -40,7 +40,7 @@ #include "../codecs/wm8731.h" #include "at91-pcm.h" -#include "at91-i2s.h" +#include "at91-ssc.h" #if 0 #define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) @@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link eti_b1_dai = { .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &at91_i2s_dai[1], + .stream_name = "WM8731 PCM", + .cpu_dai = &at91_ssc_dai[1], .codec_dai = &wm8731_dai, .init = eti_b1_wm8731_init, .ops = &eti_b1_ops, }; static struct snd_soc_machine snd_soc_machine_eti_b1 = { - .name = "ETI_B1", + .name = "ETI_B1_WM8731", .dai_link = &eti_b1_dai, .num_links = 1, }; diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index ec2a2787957a..e5fb437b86e8 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -10,6 +10,10 @@ config SND_SOC_WM8750 tristate depends on SND_SOC +config SND_SOC_WM8753 + tristate + depends on SND_SOC + config SND_SOC_WM9712 tristate depends on SND_SOC diff --git a/trunk/sound/soc/codecs/Makefile b/trunk/sound/soc/codecs/Makefile index 3249a6e4f1d0..e39a747a17cf 100644 --- a/trunk/sound/soc/codecs/Makefile +++ b/trunk/sound/soc/codecs/Makefile @@ -1,9 +1,11 @@ snd-soc-ac97-objs := ac97.o snd-soc-wm8731-objs := wm8731.o snd-soc-wm8750-objs := wm8750.o +snd-soc-wm8753-objs := wm8753.o snd-soc-wm9712-objs := wm9712.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o +obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o diff --git a/trunk/sound/soc/codecs/ac97.c b/trunk/sound/soc/codecs/ac97.c index 55bc55eb6e24..0cdef971cbd3 100644 --- a/trunk/sound/soc/codecs/ac97.c +++ b/trunk/sound/soc/codecs/ac97.c @@ -60,6 +60,7 @@ static struct snd_soc_codec_dai ac97_dai = { .ops = { .prepare = ac97_prepare,}, }; +EXPORT_SYMBOL_GPL(ac97_dai); static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) diff --git a/trunk/sound/soc/codecs/ac97.h b/trunk/sound/soc/codecs/ac97.h index 930ddfc2321a..2bf6d69fd069 100644 --- a/trunk/sound/soc/codecs/ac97.h +++ b/trunk/sound/soc/codecs/ac97.h @@ -14,5 +14,6 @@ #define __LINUX_SND_SOC_AC97_H extern struct snd_soc_codec_device soc_codec_dev_ac97; +extern struct snd_soc_codec_dai ac97_dai; #endif diff --git a/trunk/sound/soc/codecs/wm8750.c b/trunk/sound/soc/codecs/wm8750.c index 7073e8e294fc..28684eeda738 100644 --- a/trunk/sound/soc/codecs/wm8750.c +++ b/trunk/sound/soc/codecs/wm8750.c @@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev) codec->dai = &wm8750_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(wm8750_reg); - codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL); + codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); if (codec->reg_cache == NULL) return -ENOMEM; diff --git a/trunk/sound/soc/codecs/wm8753.c b/trunk/sound/soc/codecs/wm8753.c new file mode 100644 index 000000000000..efced934566d --- /dev/null +++ b/trunk/sound/soc/codecs/wm8753.c @@ -0,0 +1,1811 @@ +/* + * wm8753.c -- WM8753 ALSA Soc Audio driver + * + * Copyright 2003 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Notes: + * The WM8753 is a low power, high quality stereo codec with integrated PCM + * codec designed for portable digital telephony applications. + * + * Dual DAI:- + * + * This driver support 2 DAI PCM's. This makes the default PCM available for + * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for + * voice. + * + * Please note that the voice PCM can be connected directly to a Bluetooth + * codec or GSM modem and thus cannot be read or written to, although it is + * available to be configured with snd_hw_params(), etc and kcontrols in the + * normal alsa manner. + * + * Fast DAI switching:- + * + * The driver can now fast switch between the DAI configurations via a + * an alsa kcontrol. This allows the PCM to remain open. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8753.h" + +#define AUDIO_NAME "wm8753" +#define WM8753_VERSION "0.16" + +/* + * Debug + */ + +#define WM8753_DEBUG 0 + +#ifdef WM8753_DEBUG +#define dbg(format, arg...) \ + printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif +#define err(format, arg...) \ + printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) +#define info(format, arg...) \ + printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) +#define warn(format, arg...) \ + printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) + +static int caps_charge = 2000; +module_param(caps_charge, int, 0); +MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); + +static void wm8753_set_dai_mode(struct snd_soc_codec *codec, + unsigned int mode); + +/* codec private data */ +struct wm8753_priv { + unsigned int sysclk; + unsigned int pcmclk; +}; + +/* + * wm8753 register cache + * We can't read the WM8753 register space when we + * are using 2 wire for device control, so we cache them instead. + */ +static const u16 wm8753_reg[] = { + 0x0008, 0x0000, 0x000a, 0x000a, + 0x0033, 0x0000, 0x0007, 0x00ff, + 0x00ff, 0x000f, 0x000f, 0x007b, + 0x0000, 0x0032, 0x0000, 0x00c3, + 0x00c3, 0x00c0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0055, + 0x0005, 0x0050, 0x0055, 0x0050, + 0x0055, 0x0050, 0x0055, 0x0079, + 0x0079, 0x0079, 0x0079, 0x0079, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0097, 0x0097, 0x0000, 0x0004, + 0x0000, 0x0083, 0x0024, 0x01ba, + 0x0000, 0x0083, 0x0024, 0x01ba, + 0x0000, 0x0000 +}; + +/* + * read wm8753 register cache + */ +static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) + return -1; + return cache[reg - 1]; +} + +/* + * write wm8753 register cache + */ +static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + if (reg < 1 || reg > 0x3f) + return; + cache[reg - 1] = value; +} + +/* + * write to the WM8753 register space + */ +static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + u8 data[2]; + + /* data is + * D15..D9 WM8753 register offset + * D8...D0 register data + */ + data[0] = (reg << 1) | ((value >> 8) & 0x0001); + data[1] = value & 0x00ff; + + wm8753_write_reg_cache (codec, reg, value); + if (codec->hw_write(codec->control_data, data, 2) == 2) + return 0; + else + return -EIO; +} + +#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) + +/* + * WM8753 Controls + */ +static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"}; +static const char *wm8753_base_filter[] = + {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz", + "100Hz @ 8kHz", "200Hz @ 8kHz"}; +static const char *wm8753_treble[] = {"8kHz", "4kHz"}; +static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"}; +static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"}; +static const char *wm8753_3d_func[] = {"Capture", "Playback"}; +static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"}; +static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"}; +static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"}; +static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"}; +static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"}; +static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2", + "Line 1", "Line 2"}; +static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"}; +static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"}; +static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"}; +static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"}; +static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2", + "Right PGA"}; +static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right", + "Left + Right"}; +static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"}; +static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"}; +static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"}; +static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"}; +static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left", + "Analogue Mix Right", "Digital Mono Mix"}; +static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k", + "82Hz @ 8kHz", "170Hz @ 8kHz"}; +static const char *wm8753_adc_filter[] = {"HiFi", "Voice"}; +static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"}; +static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"}; +static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC", + "Channel Swap"}; + +static const struct soc_enum wm8753_enum[] = { +SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base), +SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter), +SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble), +SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func), +SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type), +SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func), +SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc), +SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc), +SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp), +SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix), +SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase), +SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix), +SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux), +SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux), +SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux), +SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel), +SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux), +SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src), +SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3), +SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4), +SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel), +SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel), +SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc), +SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp), +SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter), +SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel), +SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode), +SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel), +}; + + +static int wm8753_get_dai(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + + ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; + return 0; +} + +static int wm8753_set_dai(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + + if (((mode &0xc) >> 2) == ucontrol->value.integer.value[0]) + return 0; + + mode &= 0xfff3; + mode |= (ucontrol->value.integer.value[0] << 2); + + wm8753_write(codec, WM8753_IOCTL, mode); + wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]); + return 1; +} + +static const struct snd_kcontrol_new wm8753_snd_controls[] = { +SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0), + +SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0), + +SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0), +SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0), + +SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0), + +SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1), +SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1), +SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1), + +SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0), +SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0), + +SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1), +SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1), +SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 4, 7, 1), +SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0), + +SOC_ENUM("Bass Boost", wm8753_enum[0]), +SOC_ENUM("Bass Filter", wm8753_enum[1]), +SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1), + +SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1), +SOC_ENUM("Treble Cut-off", wm8753_enum[2]), + +SOC_DOUBLE("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1), +SOC_SINGLE("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1), + +SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0), +SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0), +SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1), + +SOC_ENUM("Capture Filter Select", wm8753_enum[23]), +SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]), +SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1), + +SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0), +SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0), +SOC_ENUM("ALC Capture Function", wm8753_enum[3]), +SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0), +SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1), +SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1), +SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0), +SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0), +SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]), +SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0), + +SOC_ENUM("3D Function", wm8753_enum[5]), +SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]), +SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]), +SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0), +SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0), + +SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0), +SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0), + +SOC_ENUM("De-emphasis", wm8753_enum[8]), +SOC_ENUM("Playback Mono Mix", wm8753_enum[9]), +SOC_ENUM("Playback Phase", wm8753_enum[10]), + +SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0), +SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0), + +SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai), + +SOC_ENUM("ADC Data Select", wm8753_enum[27]), +}; + +/* add non dapm controls */ +static int wm8753_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8753_snd_controls[i],codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + +/* + * _DAPM_ Controls + */ + +/* Left Mixer */ +static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0), +}; + +/* Right mixer */ +static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0), +}; + +/* Mono mixer */ +static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = { +SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0), +}; + +/* Mono 2 Mux */ +static const struct snd_kcontrol_new wm8753_mono2_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[17]); + +/* Out 3 Mux */ +static const struct snd_kcontrol_new wm8753_out3_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[18]); + +/* Out 4 Mux */ +static const struct snd_kcontrol_new wm8753_out4_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[19]); + +/* ADC Mono Mix */ +static const struct snd_kcontrol_new wm8753_adc_mono_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[22]); + +/* Record mixer */ +static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0), +SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0), +SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0), +}; + +/* Left ADC mux */ +static const struct snd_kcontrol_new wm8753_adc_left_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[21]); + +/* Right ADC mux */ +static const struct snd_kcontrol_new wm8753_adc_right_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[20]); + +/* MIC mux */ +static const struct snd_kcontrol_new wm8753_mic_mux_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[16]); + +/* ALC mixer */ +static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = { +SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0), +SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0), +SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0), +SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0), +}; + +/* Left Line mux */ +static const struct snd_kcontrol_new wm8753_line_left_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[14]); + +/* Right Line mux */ +static const struct snd_kcontrol_new wm8753_line_right_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[13]); + +/* Mono Line mux */ +static const struct snd_kcontrol_new wm8753_line_mono_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[12]); + +/* Line mux and mixer */ +static const struct snd_kcontrol_new wm8753_line_mux_mix_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[11]); + +/* Rx mux and mixer */ +static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[15]); + +/* Mic Selector Mux */ +static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[25]); + +static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { +SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0), +SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0, + &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)), +SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0), +SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0), +SND_SOC_DAPM_OUTPUT("LOUT1"), +SND_SOC_DAPM_OUTPUT("LOUT2"), +SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0, + &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)), +SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0), +SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0), +SND_SOC_DAPM_OUTPUT("ROUT1"), +SND_SOC_DAPM_OUTPUT("ROUT2"), +SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0, + &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)), +SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0), +SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0), +SND_SOC_DAPM_OUTPUT("MONO1"), +SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls), +SND_SOC_DAPM_OUTPUT("MONO2"), +SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0), +SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls), +SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0), +SND_SOC_DAPM_OUTPUT("OUT3"), +SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls), +SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0), +SND_SOC_DAPM_OUTPUT("OUT4"), +SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0, + &wm8753_record_mixer_controls[0], + ARRAY_SIZE(wm8753_record_mixer_controls)), +SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0), +SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0), +SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0, + &wm8753_adc_mono_controls), +SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0, + &wm8753_adc_mono_controls), +SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0, + &wm8753_adc_left_controls), +SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0, + &wm8753_adc_right_controls), +SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0, + &wm8753_mic_mux_controls), +SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0), +SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0, + &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)), +SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_left_controls), +SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_right_controls), +SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_mono_controls), +SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0, + &wm8753_line_mux_mix_controls), +SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0, + &wm8753_rx_mux_mix_controls), +SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0), +SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0), +SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0, + &wm8753_mic_sel_mux_controls), +SND_SOC_DAPM_INPUT("LINE1"), +SND_SOC_DAPM_INPUT("LINE2"), +SND_SOC_DAPM_INPUT("RXP"), +SND_SOC_DAPM_INPUT("RXN"), +SND_SOC_DAPM_INPUT("ACIN"), +SND_SOC_DAPM_OUTPUT("ACOP"), +SND_SOC_DAPM_INPUT("MIC1N"), +SND_SOC_DAPM_INPUT("MIC1"), +SND_SOC_DAPM_INPUT("MIC2N"), +SND_SOC_DAPM_INPUT("MIC2"), +SND_SOC_DAPM_VMID("VREF"), +}; + +static const char *audio_map[][3] = { + /* left mixer */ + {"Left Mixer", "Left Playback Switch", "Left DAC"}, + {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"}, + + /* right mixer */ + {"Right Mixer", "Right Playback Switch", "Right DAC"}, + {"Right Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"}, + + /* mono mixer */ + {"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Mono Mixer", "Left Playback Switch", "Left DAC"}, + {"Mono Mixer", "Right Playback Switch", "Right DAC"}, + {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"}, + + /* left out */ + {"Left Out 1", NULL, "Left Mixer"}, + {"Left Out 2", NULL, "Left Mixer"}, + {"LOUT1", NULL, "Left Out 1"}, + {"LOUT2", NULL, "Left Out 2"}, + + /* right out */ + {"Right Out 1", NULL, "Right Mixer"}, + {"Right Out 2", NULL, "Right Mixer"}, + {"ROUT1", NULL, "Right Out 1"}, + {"ROUT2", NULL, "Right Out 2"}, + + /* mono 1 out */ + {"Mono Out 1", NULL, "Mono Mixer"}, + {"MONO1", NULL, "Mono Out 1"}, + + /* mono 2 out */ + {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"}, + {"Mono 2 Mux", "Inverted Mono 1", "MONO1"}, + {"Mono 2 Mux", "Left", "Left Mixer"}, + {"Mono 2 Mux", "Right", "Right Mixer"}, + {"Mono Out 2", NULL, "Mono 2 Mux"}, + {"MONO2", NULL, "Mono Out 2"}, + + /* out 3 */ + {"Out3 Left + Right", NULL, "Left Mixer"}, + {"Out3 Left + Right", NULL, "Right Mixer"}, + {"Out3 Mux", "VREF", "VREF"}, + {"Out3 Mux", "Left + Right", "Out3 Left + Right"}, + {"Out3 Mux", "ROUT2", "ROUT2"}, + {"Out 3", NULL, "Out3 Mux"}, + {"OUT3", NULL, "Out 3"}, + + /* out 4 */ + {"Out4 Mux", "VREF", "VREF"}, + {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, + {"Out4 Mux", "LOUT2", "LOUT2"}, + {"Out 4", NULL, "Out4 Mux"}, + {"OUT4", NULL, "Out 4"}, + + /* record mixer */ + {"Playback Mixer", "Left Capture Switch", "Left Mixer"}, + {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"}, + {"Playback Mixer", "Right Capture Switch", "Right Mixer"}, + + /* Mic/SideTone Mux */ + {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"}, + {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"}, + {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"}, + {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"}, + + /* Capture Left Mux */ + {"Capture Left Mux", "PGA", "Left Capture Volume"}, + {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"}, + {"Capture Left Mux", "Line", "LINE1"}, + + /* Capture Right Mux */ + {"Capture Right Mux", "PGA", "Right Capture Volume"}, + {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, + {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, + + /* Mono Capture mixer-mux */ + {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, + {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"}, + {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"}, + {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"}, + {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"}, + {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"}, + {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"}, + {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"}, + {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"}, + + /* ADC */ + {"Left ADC", NULL, "Capture Left Mixer"}, + {"Right ADC", NULL, "Capture Right Mixer"}, + + /* Left Capture Volume */ + {"Left Capture Volume", NULL, "ACIN"}, + + /* Right Capture Volume */ + {"Right Capture Volume", NULL, "Mic 2 Volume"}, + + /* ALC Mixer */ + {"ALC Mixer", "Line Capture Switch", "Line Mixer"}, + {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"}, + {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"}, + {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"}, + + /* Line Left Mux */ + {"Line Left Mux", "Line 1", "LINE1"}, + {"Line Left Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Right Mux */ + {"Line Right Mux", "Line 2", "LINE2"}, + {"Line Right Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Mono Mux */ + {"Line Mono Mux", "Line Mix", "Line Mixer"}, + {"Line Mono Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Mixer/Mux */ + {"Line Mixer", "Line 1 + 2", "LINE1"}, + {"Line Mixer", "Line 1 - 2", "LINE1"}, + {"Line Mixer", "Line 1 + 2", "LINE2"}, + {"Line Mixer", "Line 1 - 2", "LINE2"}, + {"Line Mixer", "Line 1", "LINE1"}, + {"Line Mixer", "Line 2", "LINE2"}, + + /* Rx Mixer/Mux */ + {"Rx Mixer", "RXP - RXN", "RXP"}, + {"Rx Mixer", "RXP + RXN", "RXP"}, + {"Rx Mixer", "RXP - RXN", "RXN"}, + {"Rx Mixer", "RXP + RXN", "RXN"}, + {"Rx Mixer", "RXP", "RXP"}, + {"Rx Mixer", "RXN", "RXN"}, + + /* Mic 1 Volume */ + {"Mic 1 Volume", NULL, "MIC1N"}, + {"Mic 1 Volume", NULL, "Mic Selection Mux"}, + + /* Mic 2 Volume */ + {"Mic 2 Volume", NULL, "MIC2N"}, + {"Mic 2 Volume", NULL, "MIC2"}, + + /* Mic Selector Mux */ + {"Mic Selection Mux", "Mic 1", "MIC1"}, + {"Mic Selection Mux", "Mic 2", "MIC2N"}, + {"Mic Selection Mux", "Mic 3", "MIC2"}, + + /* ACOP */ + {"ACOP", NULL, "ALC Mixer"}, + + /* terminator */ + {NULL, NULL, NULL}, +}; + +static int wm8753_add_widgets(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) + snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); + + /* set up the WM8753 audio map */ + for (i = 0; audio_map[i][0] != NULL; i++) { + snd_soc_dapm_connect_input(codec, audio_map[i][0], + audio_map[i][1], audio_map[i][2]); + } + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +/* PLL divisors */ +struct _pll_div { + u32 div2:1; + u32 n:4; + u32 k:24; +}; + +/* The size in bits of the pll divide multiplied by 10 + * to allow rounding later */ +#define FIXED_PLL_SIZE ((1 << 22) * 10) + +static void pll_factors(struct _pll_div *pll_div, unsigned int target, + unsigned int source) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod; + + Ndiv = target / source; + if (Ndiv < 6) { + source >>= 1; + pll_div->div2 = 1; + Ndiv = target / source; + } else + pll_div->div2 = 0; + + if ((Ndiv < 6) || (Ndiv > 12)) + printk(KERN_WARNING + "WM8753 N value outwith recommended range! N = %d\n",Ndiv); + + pll_div->n = Ndiv; + Nmod = target % source; + Kpart = FIXED_PLL_SIZE * (long long)Nmod; + + do_div(Kpart, source); + + K = Kpart & 0xFFFFFFFF; + + /* Check if we need to round */ + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + K /= 10; + + pll_div->k = K; +} + +static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai, + int pll_id, unsigned int freq_in, unsigned int freq_out) +{ + u16 reg, enable; + int offset; + struct snd_soc_codec *codec = codec_dai->codec; + + if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2) + return -ENODEV; + + if (pll_id == WM8753_PLL1) { + offset = 0; + enable = 0x10; + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; + } else { + offset = 4; + enable = 0x8; + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; + } + + if (!freq_in || !freq_out) { + /* disable PLL */ + wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); + wm8753_write(codec, WM8753_CLOCK, reg); + return 0; + } else { + u16 value = 0; + struct _pll_div pll_div; + + pll_factors(&pll_div, freq_out * 8, freq_in); + + /* set up N and K PLL divisor ratios */ + /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ + value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); + wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); + + /* bits 8:0 = PLL_K[17:9] */ + value = (pll_div.k & 0x03fe00) >> 9; + wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); + + /* bits 8:0 = PLL_K[8:0] */ + value = pll_div.k & 0x0001ff; + wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); + + /* set PLL as input and enable */ + wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | + (pll_div.div2 << 3)); + wm8753_write(codec, WM8753_CLOCK, reg | enable); + } + return 0; +} + +struct _coeff_div { + u32 mclk; + u32 rate; + u8 sr:5; + u8 usb:1; +}; + +/* codec hifi mclk (after PLL) clock divider coefficients */ +static const struct _coeff_div coeff_div[] = { + /* 8k */ + {12288000, 8000, 0x6, 0x0}, + {11289600, 8000, 0x16, 0x0}, + {18432000, 8000, 0x7, 0x0}, + {16934400, 8000, 0x17, 0x0}, + {12000000, 8000, 0x6, 0x1}, + + /* 11.025k */ + {11289600, 11025, 0x18, 0x0}, + {16934400, 11025, 0x19, 0x0}, + {12000000, 11025, 0x19, 0x1}, + + /* 16k */ + {12288000, 16000, 0xa, 0x0}, + {18432000, 16000, 0xb, 0x0}, + {12000000, 16000, 0xa, 0x1}, + + /* 22.05k */ + {11289600, 22050, 0x1a, 0x0}, + {16934400, 22050, 0x1b, 0x0}, + {12000000, 22050, 0x1b, 0x1}, + + /* 32k */ + {12288000, 32000, 0xc, 0x0}, + {18432000, 32000, 0xd, 0x0}, + {12000000, 32000, 0xa, 0x1}, + + /* 44.1k */ + {11289600, 44100, 0x10, 0x0}, + {16934400, 44100, 0x11, 0x0}, + {12000000, 44100, 0x11, 0x1}, + + /* 48k */ + {12288000, 48000, 0x0, 0x0}, + {18432000, 48000, 0x1, 0x0}, + {12000000, 48000, 0x0, 0x1}, + + /* 88.2k */ + {11289600, 88200, 0x1e, 0x0}, + {16934400, 88200, 0x1f, 0x0}, + {12000000, 88200, 0x1f, 0x1}, + + /* 96k */ + {12288000, 96000, 0xe, 0x0}, + {18432000, 96000, 0xf, 0x0}, + {12000000, 96000, 0xe, 0x1}, +}; + +static int get_coeff(int mclk, int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) + return i; + } + return -EINVAL; +} + +/* + * Clock after PLL and dividers + */ +static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8753_priv *wm8753 = codec->private_data; + + switch (freq) { + case 11289600: + case 12000000: + case 12288000: + case 16934400: + case 18432000: + if (clk_id == WM8753_MCLK) { + wm8753->sysclk = freq; + return 0; + } else if (clk_id == WM8753_PCMCLK) { + wm8753->pcmclk = freq; + return 0; + } + break; + } + return -EINVAL; +} + +/* + * Set's ADC and Voice DAC format. + */ +static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + voice |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + voice |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + voice |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + voice |= 0x0013; + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_PCM, voice); + return 0; +} + +/* + * Set PCM DAI bit size and sample rate. + */ +static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + struct wm8753_priv *wm8753 = codec->private_data; + u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; + u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + voice |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + voice |= 0x0008; + break; + case SNDRV_PCM_FORMAT_S32_LE: + voice |= 0x000c; + break; + } + + /* sample rate */ + if (params_rate(params) * 384 == wm8753->pcmclk) + srate |= 0x80; + wm8753_write(codec, WM8753_SRATE1, srate); + + wm8753_write(codec, WM8753_PCM, voice); + return 0; +} + +/* + * Set's PCM dai fmt and BCLK. + */ +static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 voice, ioctl; + + voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; + ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + ioctl |= 0x2; + case SND_SOC_DAIFMT_CBM_CFS: + voice |= 0x0040; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + voice |= 0x0080; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + voice &= ~0x0010; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + voice |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + voice |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + voice |= 0x0010; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_PCM, voice); + wm8753_write(codec, WM8753_IOCTL, ioctl); + return 0; +} + +static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, + int div_id, int div) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + + switch (div_id) { + case WM8753_PCMDIV: + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; + wm8753_write(codec, WM8753_CLOCK, reg | div); + break; + case WM8753_BCLKDIV: + reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; + wm8753_write(codec, WM8753_SRATE2, reg | div); + break; + case WM8753_VXCLKDIV: + reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; + wm8753_write(codec, WM8753_SRATE2, reg | div); + break; + default: + return -EINVAL; + } + return 0; +} + +/* + * Set's HiFi DAC format. + */ +static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + hifi |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + hifi |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + hifi |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + hifi |= 0x0013; + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + return 0; +} + +/* + * Set's I2S DAI format. + */ +static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 ioctl, hifi; + + hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; + ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + ioctl |= 0x1; + case SND_SOC_DAIFMT_CBM_CFS: + hifi |= 0x0040; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + hifi |= 0x0080; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + hifi &= ~0x0010; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + hifi |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + hifi |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + hifi |= 0x0010; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + wm8753_write(codec, WM8753_IOCTL, ioctl); + return 0; +} + +/* + * Set PCM DAI bit size and sample rate. + */ +static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + struct wm8753_priv *wm8753 = codec->private_data; + u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; + u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; + int coeff; + + /* is digital filter coefficient valid ? */ + coeff = get_coeff(wm8753->sysclk, params_rate(params)); + if (coeff < 0) { + printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); + return coeff; + } + wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | + coeff_div[coeff].usb); + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + hifi |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + hifi |= 0x0008; + break; + case SNDRV_PCM_FORMAT_S32_LE: + hifi |= 0x000c; + break; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + return 0; +} + +static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as pcmclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock); + + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_pcm_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as pcmclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock); + + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as mclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock | 0x4); + + if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; + + /* the digital mute covers the HiFi and Voice DAC's on the WM8753. + * make sure we check if they are not both active when we mute */ + if (mute && dai->id == 1) { + if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || + !wm8753_dai[WM8753_DAI_HIFI].playback.active) + wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + } else { + if (mute) + wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + else + wm8753_write(codec, WM8753_DAC, mute_reg); + } + + return 0; +} + +static int wm8753_dapm_event(struct snd_soc_codec *codec, int event) +{ + u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; + + switch (event) { + case SNDRV_CTL_POWER_D0: /* full On */ + /* set vmid to 50k and unmute dac */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); + break; + case SNDRV_CTL_POWER_D1: /* partial On */ + case SNDRV_CTL_POWER_D2: /* partial On */ + /* set vmid to 5k for quick power up */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); + break; + case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + /* mute dac and set vmid to 500k, enable VREF */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); + break; + case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + wm8753_write(codec, WM8753_PWR1, 0x0001); + break; + } + codec->dapm_state = event; + return 0; +} + +#define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +/* + * The WM8753 supports upto 4 different and mutually exclusive DAI + * configurations. This gives 2 PCM's available for use, hifi and voice. + * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI + * is connected between the wm8753 and a BT codec or GSM modem. + * + * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI + * 2. Voice over HIFI DAI - HIFI disabled + * 3. Voice disabled - HIFI over HIFI + * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture + */ +static const struct snd_soc_codec_dai wm8753_all_dai[] = { +/* DAI HiFi mode 1 */ +{ .name = "WM8753 HiFi", + .id = 1, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { /* dummy for fast DAI switching */ + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1h_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 1 */ +{ .name = "WM8753 Voice", + .id = 1, + .playback = { + .stream_name = "Voice Playback", + .channels_min = 1, + .channels_max = 1, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_pcm_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1v_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI HiFi mode 2 - dummy */ +{ .name = "WM8753 HiFi", + .id = 2, +}, +/* DAI Voice mode 2 */ +{ .name = "WM8753 Voice", + .id = 2, + .playback = { + .stream_name = "Voice Playback", + .channels_min = 1, + .channels_max = 1, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_pcm_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode2_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI HiFi mode 3 */ +{ .name = "WM8753 HiFi", + .id = 3, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 3 - dummy */ +{ .name = "WM8753 Voice", + .id = 3, +}, +/* DAI HiFi mode 4 */ +{ .name = "WM8753 HiFi", + .id = 4, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 4 - dummy */ +{ .name = "WM8753 Voice", + .id = 4, +}, +}; + +struct snd_soc_codec_dai wm8753_dai[2]; +EXPORT_SYMBOL_GPL(wm8753_dai); + +static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) +{ + if (mode < 4) { + int playback_active, capture_active, codec_active, pop_wait; + void *private_data; + + playback_active = wm8753_dai[0].playback.active; + capture_active = wm8753_dai[0].capture.active; + codec_active = wm8753_dai[0].active; + private_data = wm8753_dai[0].private_data; + pop_wait = wm8753_dai[0].pop_wait; + wm8753_dai[0] = wm8753_all_dai[mode << 1]; + wm8753_dai[0].playback.active = playback_active; + wm8753_dai[0].capture.active = capture_active; + wm8753_dai[0].active = codec_active; + wm8753_dai[0].private_data = private_data; + wm8753_dai[0].pop_wait = pop_wait; + + playback_active = wm8753_dai[1].playback.active; + capture_active = wm8753_dai[1].capture.active; + codec_active = wm8753_dai[1].active; + private_data = wm8753_dai[1].private_data; + pop_wait = wm8753_dai[1].pop_wait; + wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; + wm8753_dai[1].playback.active = playback_active; + wm8753_dai[1].capture.active = capture_active; + wm8753_dai[1].active = codec_active; + wm8753_dai[1].private_data = private_data; + wm8753_dai[1].pop_wait = pop_wait; + } + wm8753_dai[0].codec = codec; + wm8753_dai[1].codec = codec; +} + +static void wm8753_work(struct work_struct *work) +{ + struct snd_soc_codec *codec = + container_of(work, struct snd_soc_codec, delayed_work.work); + wm8753_dapm_event(codec, codec->dapm_state); +} + +static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + /* we only need to suspend if we are a valid card */ + if(!codec->card) + return 0; + + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + return 0; +} + +static int wm8753_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + int i; + u8 data[2]; + u16 *cache = codec->reg_cache; + + /* we only need to resume if we are a valid card */ + if(!codec->card) + return 0; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { + if (i + 1 == WM8753_RESET) + continue; + data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); + } + + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + + /* charge wm8753 caps */ + if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); + codec->dapm_state = SNDRV_CTL_POWER_D0; + schedule_delayed_work(&codec->delayed_work, + msecs_to_jiffies(caps_charge)); + } + + return 0; +} + +/* + * initialise the WM8753 driver + * register the mixer and dsp interfaces with the kernel + */ +static int wm8753_init(struct snd_soc_device *socdev) +{ + struct snd_soc_codec *codec = socdev->codec; + int reg, ret = 0; + + codec->name = "WM8753"; + codec->owner = THIS_MODULE; + codec->read = wm8753_read_reg_cache; + codec->write = wm8753_write; + codec->dapm_event = wm8753_dapm_event; + codec->dai = wm8753_dai; + codec->num_dai = 2; + codec->reg_cache_size = sizeof(wm8753_reg); + codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); + + if (codec->reg_cache == NULL) + return -ENOMEM; + + wm8753_set_dai_mode(codec, 0); + + wm8753_reset(codec); + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + printk(KERN_ERR "wm8753: failed to create pcms\n"); + goto pcm_err; + } + + /* charge output caps */ + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); + codec->dapm_state = SNDRV_CTL_POWER_D3hot; + schedule_delayed_work(&codec->delayed_work, + msecs_to_jiffies(caps_charge)); + + /* set the update bits */ + reg = wm8753_read_reg_cache(codec, WM8753_LDAC); + wm8753_write(codec, WM8753_LDAC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RDAC); + wm8753_write(codec, WM8753_RDAC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LADC); + wm8753_write(codec, WM8753_LADC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RADC); + wm8753_write(codec, WM8753_RADC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); + wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); + wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); + wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); + wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); + wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); + wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); + + wm8753_add_controls(codec); + wm8753_add_widgets(codec); + ret = snd_soc_register_card(socdev); + if (ret < 0) { + printk(KERN_ERR "wm8753: failed to register card\n"); + goto card_err; + } + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + kfree(codec->reg_cache); + return ret; +} + +/* If the i2c layer weren't so broken, we could pass this kind of data + around */ +static struct snd_soc_device *wm8753_socdev; + +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + +/* + * WM8753 2 wire address is determined by GPIO5 + * state during powerup. + * low = 0x1a + * high = 0x1b + */ +static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; + +/* Magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; + +static struct i2c_driver wm8753_i2c_driver; +static struct i2c_client client_template; + +static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) +{ + struct snd_soc_device *socdev = wm8753_socdev; + struct wm8753_setup_data *setup = socdev->codec_data; + struct snd_soc_codec *codec = socdev->codec; + struct i2c_client *i2c; + int ret; + + if (addr != setup->i2c_address) + return -ENODEV; + + client_template.adapter = adap; + client_template.addr = addr; + + i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); + if (i2c == NULL){ + kfree(codec); + return -ENOMEM; + } + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; + + ret = i2c_attach_client(i2c); + if (ret < 0) { + err("failed to attach codec at addr %x\n", addr); + goto err; + } + + ret = wm8753_init(socdev); + if (ret < 0) { + err("failed to initialise WM8753\n"); + goto err; + } + + return ret; + +err: + kfree(codec); + kfree(i2c); + return ret; +} + +static int wm8753_i2c_detach(struct i2c_client *client) +{ + struct snd_soc_codec *codec = i2c_get_clientdata(client); + i2c_detach_client(client); + kfree(codec->reg_cache); + kfree(client); + return 0; +} + +static int wm8753_i2c_attach(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, wm8753_codec_probe); +} + +/* corgi i2c codec control layer */ +static struct i2c_driver wm8753_i2c_driver = { + .driver = { + .name = "WM8753 I2C Codec", + .owner = THIS_MODULE, + }, + .id = I2C_DRIVERID_WM8753, + .attach_adapter = wm8753_i2c_attach, + .detach_client = wm8753_i2c_detach, + .command = NULL, +}; + +static struct i2c_client client_template = { + .name = "WM8753", + .driver = &wm8753_i2c_driver, +}; +#endif + +static int wm8753_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct wm8753_setup_data *setup; + struct snd_soc_codec *codec; + struct wm8753_priv *wm8753; + int ret = 0; + + info("WM8753 Audio Codec %s", WM8753_VERSION); + + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); + if (wm8753 == NULL) { + kfree(codec); + return -ENOMEM; + } + + codec->private_data = wm8753; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + wm8753_socdev = socdev; + INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + if (setup->i2c_address) { + normal_i2c[0] = setup->i2c_address; + codec->hw_write = (hw_write_t)i2c_master_send; + ret = i2c_add_driver(&wm8753_i2c_driver); + if (ret != 0) + printk(KERN_ERR "can't add i2c driver"); + } +#else + /* Add other interfaces here */ +#endif + return ret; +} + +/* + * This function forces any delayed work to be queued and run. + */ +static int run_delayed_work(struct delayed_work *dwork) +{ + int ret; + + /* cancel any work waiting to be queued. */ + ret = cancel_delayed_work(dwork); + + /* if there was any work waiting then we run it now and + * wait for it's completion */ + if (ret) { + schedule_delayed_work(dwork, 0); + flush_scheduled_work(); + } + return ret; +} + +/* power down chip */ +static int wm8753_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + if (codec->control_data) + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + run_delayed_work(&codec->delayed_work); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + i2c_del_driver(&wm8753_i2c_driver); +#endif + kfree(codec->private_data); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8753 = { + .probe = wm8753_probe, + .remove = wm8753_remove, + .suspend = wm8753_suspend, + .resume = wm8753_resume, +}; + +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); + +MODULE_DESCRIPTION("ASoC WM8753 driver"); +MODULE_AUTHOR("Liam Girdwood"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8753.h b/trunk/sound/soc/codecs/wm8753.h new file mode 100644 index 000000000000..95e2a1f53169 --- /dev/null +++ b/trunk/sound/soc/codecs/wm8753.h @@ -0,0 +1,126 @@ +/* + * wm8753.h -- audio driver for WM8753 + * + * Copyright 2003 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef _WM8753_H +#define _WM8753_H + +/* WM8753 register space */ + +#define WM8753_DAC 0x01 +#define WM8753_ADC 0x02 +#define WM8753_PCM 0x03 +#define WM8753_HIFI 0x04 +#define WM8753_IOCTL 0x05 +#define WM8753_SRATE1 0x06 +#define WM8753_SRATE2 0x07 +#define WM8753_LDAC 0x08 +#define WM8753_RDAC 0x09 +#define WM8753_BASS 0x0a +#define WM8753_TREBLE 0x0b +#define WM8753_ALC1 0x0c +#define WM8753_ALC2 0x0d +#define WM8753_ALC3 0x0e +#define WM8753_NGATE 0x0f +#define WM8753_LADC 0x10 +#define WM8753_RADC 0x11 +#define WM8753_ADCTL1 0x12 +#define WM8753_3D 0x13 +#define WM8753_PWR1 0x14 +#define WM8753_PWR2 0x15 +#define WM8753_PWR3 0x16 +#define WM8753_PWR4 0x17 +#define WM8753_ID 0x18 +#define WM8753_INTPOL 0x19 +#define WM8753_INTEN 0x1a +#define WM8753_GPIO1 0x1b +#define WM8753_GPIO2 0x1c +#define WM8753_RESET 0x1f +#define WM8753_RECMIX1 0x20 +#define WM8753_RECMIX2 0x21 +#define WM8753_LOUTM1 0x22 +#define WM8753_LOUTM2 0x23 +#define WM8753_ROUTM1 0x24 +#define WM8753_ROUTM2 0x25 +#define WM8753_MOUTM1 0x26 +#define WM8753_MOUTM2 0x27 +#define WM8753_LOUT1V 0x28 +#define WM8753_ROUT1V 0x29 +#define WM8753_LOUT2V 0x2a +#define WM8753_ROUT2V 0x2b +#define WM8753_MOUTV 0x2c +#define WM8753_OUTCTL 0x2d +#define WM8753_ADCIN 0x2e +#define WM8753_INCTL1 0x2f +#define WM8753_INCTL2 0x30 +#define WM8753_LINVOL 0x31 +#define WM8753_RINVOL 0x32 +#define WM8753_MICBIAS 0x33 +#define WM8753_CLOCK 0x34 +#define WM8753_PLL1CTL1 0x35 +#define WM8753_PLL1CTL2 0x36 +#define WM8753_PLL1CTL3 0x37 +#define WM8753_PLL1CTL4 0x38 +#define WM8753_PLL2CTL1 0x39 +#define WM8753_PLL2CTL2 0x3a +#define WM8753_PLL2CTL3 0x3b +#define WM8753_PLL2CTL4 0x3c +#define WM8753_BIASCTL 0x3d +#define WM8753_ADCTL2 0x3f + +struct wm8753_setup_data { + unsigned short i2c_address; +}; + +#define WM8753_PLL1 0 +#define WM8753_PLL2 1 + +/* clock inputs */ +#define WM8753_MCLK 0 +#define WM8753_PCMCLK 1 + +/* clock divider id's */ +#define WM8753_PCMDIV 0 +#define WM8753_BCLKDIV 1 +#define WM8753_VXCLKDIV 2 + +/* PCM clock dividers */ +#define WM8753_PCM_DIV_1 (0 << 6) +#define WM8753_PCM_DIV_3 (2 << 6) +#define WM8753_PCM_DIV_5_5 (3 << 6) +#define WM8753_PCM_DIV_2 (4 << 6) +#define WM8753_PCM_DIV_4 (5 << 6) +#define WM8753_PCM_DIV_6 (6 << 6) +#define WM8753_PCM_DIV_8 (7 << 6) + +/* BCLK clock dividers */ +#define WM8753_BCLK_DIV_1 (0 << 3) +#define WM8753_BCLK_DIV_2 (1 << 3) +#define WM8753_BCLK_DIV_4 (2 << 3) +#define WM8753_BCLK_DIV_8 (3 << 3) +#define WM8753_BCLK_DIV_16 (4 << 3) + +/* VXCLK clock dividers */ +#define WM8753_VXCLK_DIV_1 (0 << 6) +#define WM8753_VXCLK_DIV_2 (1 << 6) +#define WM8753_VXCLK_DIV_4 (2 << 6) +#define WM8753_VXCLK_DIV_8 (3 << 6) +#define WM8753_VXCLK_DIV_16 (4 << 6) + +#define WM8753_DAI_HIFI 0 +#define WM8753_DAI_VOICE 1 + +extern struct snd_soc_codec_dai wm8753_dai[2]; +extern struct snd_soc_codec_device soc_codec_dev_wm8753; + +#endif diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c index ee7a691a9ba1..264413a00cac 100644 --- a/trunk/sound/soc/codecs/wm9712.c +++ b/trunk/sound/soc/codecs/wm9712.c @@ -676,14 +676,13 @@ static int wm9712_soc_probe(struct platform_device *pdev) codec = socdev->codec; mutex_init(&codec->mutex); - codec->reg_cache = - kzalloc(sizeof(u16) * ARRAY_SIZE(wm9712_reg), GFP_KERNEL); + codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); + if (codec->reg_cache == NULL) { ret = -ENOMEM; goto cache_err; } - memcpy(codec->reg_cache, wm9712_reg, sizeof(u16) * ARRAY_SIZE(wm9712_reg)); - codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9712_reg); + codec->reg_cache_size = sizeof(wm9712_reg); codec->reg_cache_step = 2; codec->name = "WM9712"; diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig index b9ab3b8e1d3e..a83e22937c27 100644 --- a/trunk/sound/soc/pxa/Kconfig +++ b/trunk/sound/soc/pxa/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Intel PXA2xx" - config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA && SND_SOC @@ -55,5 +53,3 @@ config SND_PXA2XX_SOC_TOSA help Say Y if you want to add support for SoC audio on Sharp Zaurus SL-C6000x models (Tosa). - -endmenu diff --git a/trunk/sound/soc/s3c24xx/Kconfig b/trunk/sound/soc/s3c24xx/Kconfig new file mode 100644 index 000000000000..044a3712077a --- /dev/null +++ b/trunk/sound/soc/s3c24xx/Kconfig @@ -0,0 +1,10 @@ +config SND_S3C24XX_SOC + tristate "SoC Audio for the Samsung S3C24XX chips" + depends on ARCH_S3C2410 && SND_SOC + help + Say Y or M if you want to add support for codecs attached to + the S3C24XX AC97, I2S or SSP interface. You will also need + to select the audio interfaces to support below. + +config SND_S3C24XX_SOC_I2S + tristate diff --git a/trunk/sound/soc/s3c24xx/Makefile b/trunk/sound/soc/s3c24xx/Makefile new file mode 100644 index 000000000000..6f0fffcb30f5 --- /dev/null +++ b/trunk/sound/soc/s3c24xx/Makefile @@ -0,0 +1,6 @@ +# S3c24XX Platform Support +snd-soc-s3c24xx-objs := s3c24xx-pcm.o +snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o + +obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c new file mode 100644 index 000000000000..8ca314dc8891 --- /dev/null +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -0,0 +1,441 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * + * Revision history + * 11th Dec 2006 Merged with Simtec driver + * 10th Nov 2006 Initial version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s3c24xx-pcm.h" +#include "s3c24xx-i2s.h" + +#define S3C24XX_I2S_DEBUG 0 +#if S3C24XX_I2S_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static struct s3c2410_dma_client s3c24xx_dma_client_out = { + .name = "I2S PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c24xx_dma_client_in = { + .name = "I2S PCM Stereo in" +}; + +static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { + .client = &s3c24xx_dma_client_out, + .channel = DMACH_I2S_OUT, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, +}; + +static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { + .client = &s3c24xx_dma_client_in, + .channel = DMACH_I2S_IN, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, +}; + +struct s3c24xx_i2s_info { + void __iomem *regs; + struct clk *iis_clk; +}; +static struct s3c24xx_i2s_info s3c24xx_i2s; + +static void s3c24xx_snd_txctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; + iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_TXIDLE; + iismod |= S3C2410_IISMOD_TXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_TXENABLE; + iisfcon &= ~S3C2410_IISFCON_TXDMA; + iiscon |= S3C2410_IISCON_TXIDLE; + iiscon &= ~S3C2410_IISCON_TXDMAEN; + iismod &= ~S3C2410_IISMOD_TXMODE; + + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); +} + +static void s3c24xx_snd_rxctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; + iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_RXIDLE; + iismod |= S3C2410_IISMOD_RXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_RXENABLE; + iisfcon &= ~S3C2410_IISFCON_RXDMA; + iiscon |= S3C2410_IISCON_RXIDLE; + iiscon &= ~S3C2410_IISCON_RXDMAEN; + iismod &= ~S3C2410_IISMOD_RXMODE; + + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); +} + +/* + * Wait for the LR signal to allow synchronisation to the L/R clock + * from the codec. May only be needed for slave mode. + */ +static int s3c24xx_snd_lrsync(void) +{ + u32 iiscon; + unsigned long timeout = jiffies + msecs_to_jiffies(5); + + DBG("Entered %s\n", __FUNCTION__); + + while (1) { + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + if (iiscon & S3C2410_IISCON_LRINDEX) + break; + + if (timeout < jiffies) + return -ETIMEDOUT; + } + + return 0; +} + +/* + * Check whether CPU is the master or slave + */ +static inline int s3c24xx_snd_is_clkmaster(void) +{ + DBG("Entered %s\n", __FUNCTION__); + + return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; +} + +/* + * Set S3C24xx I2S DAI format + */ +static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, + unsigned int fmt) +{ + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params r: IISMOD: %lx \n", iismod); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iismod |= S3C2410_IISMOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_LEFT_J: + iismod |= S3C2410_IISMOD_MSB; + break; + case SND_SOC_DAIFMT_I2S: + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params w: IISMOD: %lx \n", iismod); + return 0; +} + +static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; + else + rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; + + /* Working copies of register */ + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params r: IISMOD: %lx\n", iismod); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + break; + case SNDRV_PCM_FORMAT_S16_LE: + iismod |= S3C2410_IISMOD_16BIT; + break; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params w: IISMOD: %lx\n", iismod); + return 0; +} + +static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!s3c24xx_snd_is_clkmaster()) { + ret = s3c24xx_snd_lrsync(); + if (ret) + goto exit_err; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(1); + else + s3c24xx_snd_txctrl(1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(0); + else + s3c24xx_snd_txctrl(0); + break; + default: + ret = -EINVAL; + break; + } + +exit_err: + return ret; +} + +/* + * Set S3C24xx Clock source + */ +static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("Entered %s\n", __FUNCTION__); + + iismod &= ~S3C2440_IISMOD_MPLL; + + switch (clk_id) { + case S3C24XX_CLKSRC_PCLK: + break; + case S3C24XX_CLKSRC_MPLL: + iismod |= S3C2440_IISMOD_MPLL; + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + return 0; +} + +/* + * Set S3C24xx Clock dividers + */ +static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, + int div_id, int div) +{ + u32 reg; + + DBG("Entered %s\n", __FUNCTION__); + + switch (div_id) { + case S3C24XX_DIV_MCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_BCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_PRESCALER: + writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); + reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * To avoid duplicating clock code, allow machine driver to + * get the clockrate from here. + */ +u32 s3c24xx_i2s_get_clockrate(void) +{ + return clk_get_rate(s3c24xx_i2s.iis_clk); +} +EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); + +static int s3c24xx_i2s_probe(struct platform_device *pdev) +{ + DBG("Entered %s\n", __FUNCTION__); + + s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); + if (s3c24xx_i2s.regs == NULL) + return -ENXIO; + + s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis"); + if (s3c24xx_i2s.iis_clk == NULL) { + DBG("failed to get iis_clock\n"); + return -ENODEV; + } + clk_enable(s3c24xx_i2s.iis_clk); + + /* Configure the I2S pins in correct mode */ + s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); + s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); + s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + + writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); + + s3c24xx_snd_txctrl(0); + s3c24xx_snd_rxctrl(0); + + return 0; +} + +#define S3C24XX_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +struct snd_soc_cpu_dai s3c24xx_i2s_dai = { + .name = "s3c24xx-i2s", + .id = 0, + .type = SND_SOC_DAI_I2S, + .probe = s3c24xx_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = { + .trigger = s3c24xx_i2s_trigger, + .hw_params = s3c24xx_i2s_hw_params,}, + .dai_ops = { + .set_fmt = s3c24xx_i2s_set_fmt, + .set_clkdiv = s3c24xx_i2s_set_clkdiv, + .set_sysclk = s3c24xx_i2s_set_sysclk, + }, +}; +EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); + +/* Module information */ +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.h b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.h new file mode 100644 index 000000000000..537b4ecce8a3 --- /dev/null +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.h @@ -0,0 +1,37 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * Copyright 2005 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Revision history + * 10th Nov 2006 Initial version. + */ + +#ifndef S3C24XXI2S_H_ +#define S3C24XXI2S_H_ + +/* clock sources */ +#define S3C24XX_CLKSRC_PCLK 0 +#define S3C24XX_CLKSRC_MPLL 1 + +/* Clock dividers */ +#define S3C24XX_DIV_MCLK 0 +#define S3C24XX_DIV_BCLK 1 +#define S3C24XX_DIV_PRESCALER 2 + +/* prescaler */ +#define S3C24XX_PRESCALE(a,b) \ + (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) + +u32 s3c24xx_i2s_get_clockrate(void); + +extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; + +#endif /*S3C24XXI2S_H_*/ diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c new file mode 100644 index 000000000000..21dc6974d6a3 --- /dev/null +++ b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -0,0 +1,468 @@ +/* + * s3c24xx-pcm.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Revision history + * 11th Dec 2006 Merged with Simtec driver + * 10th Nov 2006 Initial version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "s3c24xx-pcm.h" + +#define S3C24XX_PCM_DEBUG 0 +#if S3C24XX_PCM_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128*1024, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = PAGE_SIZE*2, + .periods_min = 2, + .periods_max = 128, + .fifo_size = 32, +}; + +struct s3c24xx_runtime_data { + spinlock_t lock; + int state; + unsigned int dma_loaded; + unsigned int dma_limit; + unsigned int dma_period; + dma_addr_t dma_start; + dma_addr_t dma_pos; + dma_addr_t dma_end; + struct s3c24xx_pcm_dma_params *params; +}; + +/* s3c24xx_pcm_enqueue + * + * place a dma buffer onto the queue for the dma system + * to handle. +*/ +static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + dma_addr_t pos = prtd->dma_pos; + int ret; + + DBG("Entered %s\n", __FUNCTION__); + + while (prtd->dma_loaded < prtd->dma_limit) { + unsigned long len = prtd->dma_period; + + DBG("dma_loaded: %d\n",prtd->dma_loaded); + + if ((pos + len) > prtd->dma_end) { + len = prtd->dma_end - pos; + DBG(KERN_DEBUG "%s: corrected dma len %ld\n", + __FUNCTION__, len); + } + + ret = s3c2410_dma_enqueue(prtd->params->channel, + substream, pos, len); + + if (ret == 0) { + prtd->dma_loaded++; + pos += prtd->dma_period; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; + } else + break; + } + + prtd->dma_pos = pos; +} + +static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, + void *dev_id, int size, + enum s3c2410_dma_buffresult result) +{ + struct snd_pcm_substream *substream = dev_id; + struct s3c24xx_runtime_data *prtd; + + DBG("Entered %s\n", __FUNCTION__); + + if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) + return; + + prtd = substream->runtime->private_data; + + if (substream) + snd_pcm_period_elapsed(substream); + + spin_lock(&prtd->lock); + if (prtd->state & ST_RUNNING) { + prtd->dma_loaded--; + s3c24xx_pcm_enqueue(substream); + } + + spin_unlock(&prtd->lock); +} + +static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; + unsigned long totbytes = params_buffer_bytes(params); + int ret=0; + + DBG("Entered %s\n", __FUNCTION__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!dma) + return 0; + + /* prepare DMA */ + prtd->params = dma; + + DBG("params %p, client %p, channel %d\n", prtd->params, + prtd->params->client, prtd->params->channel); + + ret = s3c2410_dma_request(prtd->params->channel, + prtd->params->client, NULL); + + if (ret) { + DBG(KERN_ERR "failed to get dma channel\n"); + return ret; + } + + /* channel needs configuring for mem=>device, increment memory addr, + * sync to pclk, half-word transfers to the IIS-FIFO. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | + S3C2410_DISRCC_APB, prtd->params->dma_addr); + + s3c2410_dma_config(prtd->params->channel, + prtd->params->dma_size, + S3C2410_DCON_SYNC_PCLK | + S3C2410_DCON_HANDSHAKE); + } else { + s3c2410_dma_config(prtd->params->channel, + prtd->params->dma_size, + S3C2410_DCON_HANDSHAKE | + S3C2410_DCON_SYNC_PCLK); + + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_HW, 0x3, + prtd->params->dma_addr); + } + + s3c2410_dma_set_buffdone_fn(prtd->params->channel, + s3c24xx_audio_buffdone); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + runtime->dma_bytes = totbytes; + + spin_lock_irq(&prtd->lock); + prtd->dma_loaded = 0; + prtd->dma_limit = runtime->hw.periods_min; + prtd->dma_period = params_period_bytes(params); + prtd->dma_start = runtime->dma_addr; + prtd->dma_pos = prtd->dma_start; + prtd->dma_end = prtd->dma_start + totbytes; + spin_unlock_irq(&prtd->lock); + + return 0; +} + +static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + + DBG("Entered %s\n", __FUNCTION__); + + /* TODO - do we need to ensure DMA flushed */ + snd_pcm_set_runtime_buffer(substream, NULL); + + if (prtd->params) { + s3c2410_dma_free(prtd->params->channel, prtd->params->client); + prtd->params = NULL; + } + + return 0; +} + +static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!prtd->params) + return 0; + + /* flush the DMA channel */ + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); + prtd->dma_loaded = 0; + prtd->dma_pos = prtd->dma_start; + + /* enqueue dma buffers */ + s3c24xx_pcm_enqueue(substream); + + return ret; +} + +static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + spin_lock(&prtd->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); + break; + + default: + ret = -EINVAL; + break; + } + + spin_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t + s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + unsigned long res; + dma_addr_t src, dst; + + DBG("Entered %s\n", __FUNCTION__); + + spin_lock(&prtd->lock); + s3c2410_dma_getposition(prtd->params->channel, &src, &dst); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + res = dst - prtd->dma_start; + else + res = src - prtd->dma_start; + + spin_unlock(&prtd->lock); + + DBG("Pointer %x %x\n",src,dst); + + /* we seem to be getting the odd error from the pcm library due + * to out-of-bounds pointers. this is maybe due to the dma engine + * not having loaded the new values for the channel before being + * callled... (todo - fix ) + */ + + if (res >= snd_pcm_lib_buffer_bytes(substream)) { + if (res == snd_pcm_lib_buffer_bytes(substream)) + res = 0; + } + + return bytes_to_frames(substream->runtime, res); +} + +static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd; + + DBG("Entered %s\n", __FUNCTION__); + + snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); + + prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + runtime->private_data = prtd; + return 0; +} + +static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + + DBG("Entered %s\n", __FUNCTION__); + + if (prtd) + kfree(prtd); + else + DBG("s3c24xx_pcm_close called with prtd == NULL\n"); + + return 0; +} + +static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + DBG("Entered %s\n", __FUNCTION__); + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops s3c24xx_pcm_ops = { + .open = s3c24xx_pcm_open, + .close = s3c24xx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = s3c24xx_pcm_hw_params, + .hw_free = s3c24xx_pcm_hw_free, + .prepare = s3c24xx_pcm_prepare, + .trigger = s3c24xx_pcm_trigger, + .pointer = s3c24xx_pcm_pointer, + .mmap = s3c24xx_pcm_mmap, +}; + +static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; + + DBG("Entered %s\n", __FUNCTION__); + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + buf->bytes = size; + return 0; +} + +static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + DBG("Entered %s\n", __FUNCTION__); + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; + } +} + +static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; + +static int s3c24xx_pcm_new(struct snd_card *card, + struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) +{ + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + if (!card->dev->dma_mask) + card->dev->dma_mask = &s3c24xx_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->playback.channels_min) { + ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->capture.channels_min) { + ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } + out: + return ret; +} + +struct snd_soc_platform s3c24xx_soc_platform = { + .name = "s3c24xx-audio", + .pcm_ops = &s3c24xx_pcm_ops, + .pcm_new = s3c24xx_pcm_new, + .pcm_free = s3c24xx_pcm_free_dma_buffers, +}; + +EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); + +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.h b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.h new file mode 100644 index 000000000000..0088c79822ea --- /dev/null +++ b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.h @@ -0,0 +1,31 @@ +/* + * s3c24xx-pcm.h -- + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * ALSA PCM interface for the Samsung S3C24xx CPU + */ + +#ifndef _S3C24XX_PCM_H +#define _S3C24XX_PCM_H + +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + +struct s3c24xx_pcm_dma_params { + struct s3c2410_dma_client *client; /* stream identifier */ + int channel; /* Channel ID */ + dma_addr_t dma_addr; + int dma_size; /* Size of the DMA transfer */ +}; + +#define S3C24XX_DAI_I2S 0 + +/* platform data */ +extern struct snd_soc_platform s3c24xx_soc_platform; +extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; + +#endif diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 7caf8c7b0ac5..96bce55572a0 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -882,13 +882,15 @@ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, if (wsink->id == snd_soc_dapm_input) { if (wsource->id == snd_soc_dapm_micbias || wsource->id == snd_soc_dapm_mic || - wsink->id == snd_soc_dapm_line) + wsink->id == snd_soc_dapm_line || + wsink->id == snd_soc_dapm_output) wsink->ext = 1; } if (wsource->id == snd_soc_dapm_output) { if (wsink->id == snd_soc_dapm_spk || wsink->id == snd_soc_dapm_hp || - wsink->id == snd_soc_dapm_line) + wsink->id == snd_soc_dapm_line || + wsink->id == snd_soc_dapm_input) wsource->ext = 1; } diff --git a/trunk/sound/sparc/cs4231.c b/trunk/sound/sparc/cs4231.c index 900a00de35fd..dca0344cc1bc 100644 --- a/trunk/sound/sparc/cs4231.c +++ b/trunk/sound/sparc/cs4231.c @@ -661,11 +661,9 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd) { unsigned int what = 0; struct snd_pcm_substream *s; - struct list_head *pos; unsigned long flags; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == chip->playback_substream) { what |= CS4231_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); diff --git a/trunk/sound/usb/Kconfig b/trunk/sound/usb/Kconfig index f05d02f5b69f..315360f31278 100644 --- a/trunk/sound/usb/Kconfig +++ b/trunk/sound/usb/Kconfig @@ -29,5 +29,33 @@ config SND_USB_USX2Y To compile this driver as a module, choose M here: the module will be called snd-usb-usx2y. +config SND_USB_CAIAQ + tristate "Native Instruments USB audio devices" + depends on SND && USB + select SND_HWDEP + select SND_RAWMIDI + select SND_PCM + help + Say Y here to include support for caiaq USB audio interfaces, + namely: + + * Native Instruments RigKontrol2 + * Native Instruments Kore Controller + * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 8 DJ + + To compile this driver as a module, choose M here: the module + will be called snd-usb-caiaq. + +config SND_USB_CAIAQ_INPUT + bool "enable input device for controllers" + depends on SND_USB_CAIAQ + help + Say Y here to support input controllers like buttons, knobs, + alpha dials and analog pedals on the following products: + + * Native Instruments RigKontrol2 + * Native Instruments Audio Kontrol 1 + endmenu diff --git a/trunk/sound/usb/Makefile b/trunk/sound/usb/Makefile index 2c1dc11a72e2..aa252ef2ebfb 100644 --- a/trunk/sound/usb/Makefile +++ b/trunk/sound/usb/Makefile @@ -9,4 +9,4 @@ snd-usb-lib-objs := usbmidi.o obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o -obj-$(CONFIG_SND) += usx2y/ +obj-$(CONFIG_SND) += usx2y/ caiaq/ diff --git a/trunk/sound/usb/caiaq/Makefile b/trunk/sound/usb/caiaq/Makefile new file mode 100644 index 000000000000..455c8c58a1bd --- /dev/null +++ b/trunk/sound/usb/caiaq/Makefile @@ -0,0 +1,3 @@ +snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o + +obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o diff --git a/trunk/sound/usb/caiaq/caiaq-audio.c b/trunk/sound/usb/caiaq/caiaq-audio.c new file mode 100644 index 000000000000..0414d766ba07 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-audio.c @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SND_USB_CAIAQ_INPUT +#include +#endif + +#include "caiaq-device.h" +#include "caiaq-audio.h" + +#define N_URBS 32 +#define CLOCK_DRIFT_TOLERANCE 5 +#define FRAMES_PER_URB 8 +#define BYTES_PER_FRAME 512 +#define CHANNELS_PER_STREAM 2 +#define BYTES_PER_SAMPLE 3 +#define BYTES_PER_SAMPLE_USB 4 +#define MAX_BUFFER_SIZE (128*1024) + +#define ENDPOINT_CAPTURE 2 +#define ENDPOINT_PLAYBACK 6 + +#define MAKE_CHECKBYTE(dev,stream,i) \ + (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) + +static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER), + .formats = SNDRV_PCM_FMTBIT_S24_3BE, + .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000), + .rate_min = 44100, + .rate_max = 0, /* will overwrite later */ + .channels_min = CHANNELS_PER_STREAM, + .channels_max = CHANNELS_PER_STREAM, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 4096, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 1024, +}; + +static void +activate_substream(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream *sub) +{ + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->sub_playback[sub->number] = sub; + else + dev->sub_capture[sub->number] = sub; +} + +static void +deactivate_substream(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream *sub) +{ + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->sub_playback[sub->number] = NULL; + else + dev->sub_capture[sub->number] = NULL; +} + +static int +all_substreams_zero(struct snd_pcm_substream **subs) +{ + int i; + for (i = 0; i < MAX_STREAMS; i++) + if (subs[i] != NULL) + return 0; + return 1; +} + +static int stream_start(struct snd_usb_caiaqdev *dev) +{ + int i, ret; + + debug("stream_start(%p)\n", dev); + spin_lock_irq(&dev->spinlock); + if (dev->streaming) { + spin_unlock_irq(&dev->spinlock); + return -EINVAL; + } + + dev->input_panic = 0; + dev->output_panic = 0; + dev->first_packet = 1; + dev->streaming = 1; + + for (i = 0; i < N_URBS; i++) { + ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); + if (ret) { + log("unable to trigger initial read #%d! (ret = %d)\n", + i, ret); + dev->streaming = 0; + spin_unlock_irq(&dev->spinlock); + return -EPIPE; + } + } + + spin_unlock_irq(&dev->spinlock); + return 0; +} + +static void stream_stop(struct snd_usb_caiaqdev *dev) +{ + int i; + + debug("stream_stop(%p)\n", dev); + if (!dev->streaming) + return; + + dev->streaming = 0; + for (i = 0; i < N_URBS; i++) { + usb_unlink_urb(dev->data_urbs_in[i]); + usb_unlink_urb(dev->data_urbs_out[i]); + } +} + +static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + debug("snd_usb_caiaq_substream_open(%p)\n", substream); + substream->runtime->hw = dev->pcm_info; + snd_pcm_limit_hw_rates(substream->runtime); + return 0; +} + +static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + + debug("snd_usb_caiaq_substream_close(%p)\n", substream); + if (all_substreams_zero(dev->sub_playback) && + all_substreams_zero(dev->sub_capture)) { + /* when the last client has stopped streaming, + * all sample rates are allowed again */ + stream_stop(dev); + dev->pcm_info.rates = dev->samplerates; + } + + return 0; +} + +static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, + struct snd_pcm_hw_params *hw_params) +{ + debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub); + return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); +} + +static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub); + spin_lock_irq(&dev->spinlock); + deactivate_substream(dev, sub); + spin_unlock_irq(&dev->spinlock); + return snd_pcm_lib_free_pages(sub); +} + +/* this should probably go upstream */ +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 +#error "Change this table" +#endif + +static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, + 48000, 64000, 88200, 96000, 176400, 192000 }; + +static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) +{ + int bytes_per_sample, bpp, ret, i; + int index = substream->number; + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; + else + dev->audio_in_buf_pos[index] = 0; + + if (dev->streaming) + return 0; + + /* the first client that opens a stream defines the sample rate + * setting for all subsequent calls, until the last client closed. */ + for (i=0; i < ARRAY_SIZE(rates); i++) + if (runtime->rate == rates[i]) + dev->pcm_info.rates = 1 << i; + + snd_pcm_limit_hw_rates(runtime); + + bytes_per_sample = BYTES_PER_SAMPLE; + if (dev->spec.data_alignment == 2) + bytes_per_sample++; + + bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) + * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; + + ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate, + runtime->sample_bits, bpp); + if (ret) + return ret; + + ret = stream_start(dev); + if (ret) + return ret; + + dev->output_running = 0; + wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); + if (!dev->output_running) { + stream_stop(dev); + return -EPIPE; + } + + return 0; +} + +static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock(&dev->spinlock); + activate_substream(dev, sub); + spin_unlock(&dev->spinlock); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock(&dev->spinlock); + deactivate_substream(dev, sub); + spin_unlock(&dev->spinlock); + break; + default: + return -EINVAL; + } + + return 0; +} + +static snd_pcm_uframes_t +snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) +{ + int index = sub->number; + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + + if (dev->input_panic || dev->output_panic) + return SNDRV_PCM_POS_XRUN; + + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + return bytes_to_frames(sub->runtime, + dev->audio_out_buf_pos[index]); + else + return bytes_to_frames(sub->runtime, + dev->audio_in_buf_pos[index]); +} + +/* operators for both playback and capture */ +static struct snd_pcm_ops snd_usb_caiaq_ops = { + .open = snd_usb_caiaq_substream_open, + .close = snd_usb_caiaq_substream_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_usb_caiaq_pcm_hw_params, + .hw_free = snd_usb_caiaq_pcm_hw_free, + .prepare = snd_usb_caiaq_pcm_prepare, + .trigger = snd_usb_caiaq_pcm_trigger, + .pointer = snd_usb_caiaq_pcm_pointer +}; + +static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream **subs) +{ + int stream, pb, *cnt; + struct snd_pcm_substream *sub; + + for (stream = 0; stream < dev->n_streams; stream++) { + sub = subs[stream]; + if (!sub) + continue; + + pb = frames_to_bytes(sub->runtime, + sub->runtime->period_size); + cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + &dev->period_out_count[stream] : + &dev->period_in_count[stream]; + + if (*cnt >= pb) { + snd_pcm_period_elapsed(sub); + *cnt %= pb; + } + } +} + +static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + struct snd_pcm_substream *sub; + int stream, i; + + if (all_substreams_zero(dev->sub_capture)) + return; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->actual_length;) { + for (stream = 0; stream < dev->n_streams; stream++, i++) { + sub = dev->sub_capture[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + audio_buf[dev->audio_in_buf_pos[stream]++] + = usb_buf[i]; + dev->period_in_count[stream]++; + if (dev->audio_in_buf_pos[stream] == sz) + dev->audio_in_buf_pos[stream] = 0; + } + } + } + + spin_unlock(&dev->spinlock); +} + +static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + unsigned char check_byte; + struct snd_pcm_substream *sub; + int stream, i; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->actual_length;) { + if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { + for (stream = 0; + stream < dev->n_streams; + stream++, i++) { + if (dev->first_packet) + continue; + + check_byte = MAKE_CHECKBYTE(dev, stream, i); + + if ((usb_buf[i] & 0x3f) != check_byte) + dev->input_panic = 1; + + if (usb_buf[i] & 0x80) + dev->output_panic = 1; + } + } + dev->first_packet = 0; + + for (stream = 0; stream < dev->n_streams; stream++, i++) { + sub = dev->sub_capture[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + audio_buf[dev->audio_in_buf_pos[stream]++] = + usb_buf[i]; + dev->period_in_count[stream]++; + if (dev->audio_in_buf_pos[stream] == sz) + dev->audio_in_buf_pos[stream] = 0; + } + } + } + + spin_unlock(&dev->spinlock); +} + +static void read_in_urb(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + if (!dev->streaming) + return; + + switch (dev->spec.data_alignment) { + case 0: + read_in_urb_mode0(dev, urb, iso); + break; + case 2: + read_in_urb_mode2(dev, urb, iso); + break; + } + + if (dev->input_panic || dev->output_panic) { + debug("streaming error detected %s %s\n", + dev->input_panic ? "(input)" : "", + dev->output_panic ? "(output)" : ""); + } + + check_for_elapsed_periods(dev, dev->sub_capture); +} + +static void fill_out_urb(struct snd_usb_caiaqdev *dev, + struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + struct snd_pcm_substream *sub; + int stream, i; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->length;) { + for (stream = 0; stream < dev->n_streams; stream++, i++) { + sub = dev->sub_playback[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + usb_buf[i] = + audio_buf[dev->audio_out_buf_pos[stream]]; + dev->period_out_count[stream]++; + dev->audio_out_buf_pos[stream]++; + if (dev->audio_out_buf_pos[stream] == sz) + dev->audio_out_buf_pos[stream] = 0; + } else + usb_buf[i] = 0; + } + + /* fill in the check bytes */ + if (dev->spec.data_alignment == 2 && + i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == + (dev->n_streams * CHANNELS_PER_STREAM)) + for (stream = 0; stream < dev->n_streams; stream++, i++) + usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); + } + + spin_unlock(&dev->spinlock); + check_for_elapsed_periods(dev, dev->sub_playback); +} + +static void read_completed(struct urb *urb) +{ + struct snd_usb_caiaq_cb_info *info = urb->context; + struct snd_usb_caiaqdev *dev; + struct urb *out; + int frame, len, send_it = 0, outframe = 0; + + if (urb->status || !info) + return; + + dev = info->dev; + if (!dev->streaming) + return; + + out = dev->data_urbs_out[info->index]; + + /* read the recently received packet and send back one which has + * the same layout */ + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + if (urb->iso_frame_desc[frame].status) + continue; + + len = urb->iso_frame_desc[outframe].actual_length; + out->iso_frame_desc[outframe].length = len; + out->iso_frame_desc[outframe].actual_length = 0; + out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; + + if (len > 0) { + fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); + read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); + send_it = 1; + } + + outframe++; + } + + if (send_it) { + out->number_of_packets = FRAMES_PER_URB; + out->transfer_flags = URB_ISO_ASAP; + usb_submit_urb(out, GFP_ATOMIC); + } + + /* re-submit inbound urb */ + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; + urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; + urb->iso_frame_desc[frame].actual_length = 0; + } + + urb->number_of_packets = FRAMES_PER_URB; + urb->transfer_flags = URB_ISO_ASAP; + usb_submit_urb(urb, GFP_ATOMIC); +} + +static void write_completed(struct urb *urb) +{ + struct snd_usb_caiaq_cb_info *info = urb->context; + struct snd_usb_caiaqdev *dev = info->dev; + + if (!dev->output_running) { + dev->output_running = 1; + wake_up(&dev->prepare_wait_queue); + } +} + +static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) +{ + int i, frame; + struct urb **urbs; + struct usb_device *usb_dev = dev->chip.dev; + unsigned int pipe; + + pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? + usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : + usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); + + urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); + if (!urbs) { + log("unable to kmalloc() urbs, OOM!?\n"); + *ret = -ENOMEM; + return NULL; + } + + for (i = 0; i < N_URBS; i++) { + urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); + if (!urbs[i]) { + log("unable to usb_alloc_urb(), OOM!?\n"); + *ret = -ENOMEM; + return urbs; + } + + urbs[i]->transfer_buffer = + kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); + if (!urbs[i]->transfer_buffer) { + log("unable to kmalloc() transfer buffer, OOM!?\n"); + *ret = -ENOMEM; + return urbs; + } + + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + struct usb_iso_packet_descriptor *iso = + &urbs[i]->iso_frame_desc[frame]; + + iso->offset = BYTES_PER_FRAME * frame; + iso->length = BYTES_PER_FRAME; + } + + urbs[i]->dev = usb_dev; + urbs[i]->pipe = pipe; + urbs[i]->transfer_buffer_length = FRAMES_PER_URB + * BYTES_PER_FRAME; + urbs[i]->context = &dev->data_cb_info[i]; + urbs[i]->interval = 1; + urbs[i]->transfer_flags = URB_ISO_ASAP; + urbs[i]->number_of_packets = FRAMES_PER_URB; + urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? + read_completed : write_completed; + } + + *ret = 0; + return urbs; +} + +static void free_urbs(struct urb **urbs) +{ + int i; + + if (!urbs) + return; + + for (i = 0; i < N_URBS; i++) { + if (!urbs[i]) + continue; + + usb_kill_urb(urbs[i]); + kfree(urbs[i]->transfer_buffer); + usb_free_urb(urbs[i]); + } + + kfree(urbs); +} + +int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) +{ + int i, ret; + + dev->n_audio_in = max(dev->spec.num_analog_audio_in, + dev->spec.num_digital_audio_in) / + CHANNELS_PER_STREAM; + dev->n_audio_out = max(dev->spec.num_analog_audio_out, + dev->spec.num_digital_audio_out) / + CHANNELS_PER_STREAM; + dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); + + debug("dev->n_audio_in = %d\n", dev->n_audio_in); + debug("dev->n_audio_out = %d\n", dev->n_audio_out); + debug("dev->n_streams = %d\n", dev->n_streams); + + if (dev->n_streams > MAX_STREAMS) { + log("unable to initialize device, too many streams.\n"); + return -EINVAL; + } + + ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, + dev->n_audio_out, dev->n_audio_in, &dev->pcm); + + if (ret < 0) { + log("snd_pcm_new() returned %d\n", ret); + return ret; + } + + dev->pcm->private_data = dev; + strcpy(dev->pcm->name, dev->product_name); + + memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); + memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); + + memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, + sizeof(snd_usb_caiaq_pcm_hardware)); + + /* setup samplerates */ + dev->samplerates = dev->pcm_info.rates; + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + dev->samplerates |= SNDRV_PCM_RATE_88200; + dev->samplerates |= SNDRV_PCM_RATE_192000; + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): + dev->samplerates |= SNDRV_PCM_RATE_88200; + break; + } + + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_usb_caiaq_ops); + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_usb_caiaq_ops); + + snd_pcm_lib_preallocate_pages_for_all(dev->pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); + + dev->data_cb_info = + kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, + GFP_KERNEL); + + if (!dev->data_cb_info) + return -ENOMEM; + + for (i = 0; i < N_URBS; i++) { + dev->data_cb_info[i].dev = dev; + dev->data_cb_info[i].index = i; + } + + dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); + if (ret < 0) { + kfree(dev->data_cb_info); + free_urbs(dev->data_urbs_in); + return ret; + } + + dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); + if (ret < 0) { + kfree(dev->data_cb_info); + free_urbs(dev->data_urbs_in); + free_urbs(dev->data_urbs_out); + return ret; + } + + return 0; +} + +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev) +{ + debug("snd_usb_caiaq_audio_free (%p)\n", dev); + stream_stop(dev); + free_urbs(dev->data_urbs_in); + free_urbs(dev->data_urbs_out); + kfree(dev->data_cb_info); +} + diff --git a/trunk/sound/usb/caiaq/caiaq-audio.h b/trunk/sound/usb/caiaq/caiaq-audio.h new file mode 100644 index 000000000000..8ab1f8d9529e --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-audio.h @@ -0,0 +1,7 @@ +#ifndef CAIAQ_AUDIO_H +#define CAIAQ_AUDIO_H + +int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev); + +#endif /* CAIAQ_AUDIO_H */ diff --git a/trunk/sound/usb/caiaq/caiaq-device.c b/trunk/sound/usb/caiaq/caiaq-device.c new file mode 100644 index 000000000000..4709347326f9 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-device.c @@ -0,0 +1,436 @@ +/* + * caiaq.c: ALSA driver for caiaq/NativeInstruments devices + * + * Copyright (c) 2007 Daniel Mack + * Karsten Wiese + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "caiaq-device.h" +#include "caiaq-audio.h" +#include "caiaq-midi.h" + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT +#include "caiaq-input.h" +#endif + +MODULE_AUTHOR("Daniel Mack "); +MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," + "{Native Instruments, Kore Controller}," + "{Native Instruments, Audio Kontrol 1}" + "{Native Instruments, Audio 8 DJ}}"); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ +static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static int snd_card_used[SNDRV_CARDS]; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for the caiaq soundcard."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable the caiaq soundcard."); + +enum { + SAMPLERATE_44100 = 0, + SAMPLERATE_48000 = 1, + SAMPLERATE_96000 = 2, + SAMPLERATE_192000 = 3, + SAMPLERATE_88200 = 4, + SAMPLERATE_INVALID = 0xff +}; + +enum { + DEPTH_NONE = 0, + DEPTH_16 = 1, + DEPTH_24 = 2, + DEPTH_32 = 3 +}; + +static struct usb_device_id snd_usb_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_RIGKONTROL2 + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_KORECONTROLLER + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_AK1 + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_AUDIO8DJ + }, + { /* terminator */ } +}; + +static void usb_ep1_command_reply_dispatch (struct urb* urb) +{ + int ret; + struct snd_usb_caiaqdev *dev = urb->context; + unsigned char *buf = urb->transfer_buffer; + + if (urb->status || !dev) { + log("received EP1 urb->status = %i\n", urb->status); + return; + } + + switch(buf[0]) { + case EP1_CMD_GET_DEVICE_INFO: + memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec)); + dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version); + debug("device spec (firmware %d): audio: %d in, %d out, " + "MIDI: %d in, %d out, data alignment %d\n", + dev->spec.fw_version, + dev->spec.num_analog_audio_in, + dev->spec.num_analog_audio_out, + dev->spec.num_midi_in, + dev->spec.num_midi_out, + dev->spec.data_alignment); + + dev->spec_received++; + wake_up(&dev->ep1_wait_queue); + break; + case EP1_CMD_AUDIO_PARAMS: + dev->audio_parm_answer = buf[1]; + wake_up(&dev->ep1_wait_queue); + break; + case EP1_CMD_MIDI_READ: + snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); + break; + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + case EP1_CMD_READ_ERP: + case EP1_CMD_READ_ANALOG: + case EP1_CMD_READ_IO: + snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); + break; +#endif + } + + dev->ep1_in_urb.actual_length = 0; + ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC); + if (ret < 0) + log("unable to submit urb. OOM!?\n"); +} + +static int send_command (struct snd_usb_caiaqdev *dev, + unsigned char command, + const unsigned char *buffer, + int len) +{ + int actual_len; + struct usb_device *usb_dev = dev->chip.dev; + + if (!usb_dev) + return -EIO; + + if (len > EP1_BUFSIZE - 1) + len = EP1_BUFSIZE - 1; + + if (buffer && len > 0) + memcpy(dev->ep1_out_buf+1, buffer, len); + + dev->ep1_out_buf[0] = command; + return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), + dev->ep1_out_buf, len+1, &actual_len, 200); +} + +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, + int rate, int depth, int bpp) +{ + int ret; + char tmp[5]; + + switch (rate) { + case 44100: tmp[0] = SAMPLERATE_44100; break; + case 48000: tmp[0] = SAMPLERATE_48000; break; + case 88200: tmp[0] = SAMPLERATE_88200; break; + case 96000: tmp[0] = SAMPLERATE_96000; break; + case 192000: tmp[0] = SAMPLERATE_192000; break; + default: return -EINVAL; + } + + switch (depth) { + case 16: tmp[1] = DEPTH_16; break; + case 24: tmp[1] = DEPTH_24; break; + default: return -EINVAL; + } + + tmp[2] = bpp & 0xff; + tmp[3] = bpp >> 8; + tmp[4] = 1; /* packets per microframe */ + + debug("setting audio params: %d Hz, %d bits, %d bpp\n", + rate, depth, bpp); + + dev->audio_parm_answer = -1; + ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); + + if (ret) + return ret; + + if (!wait_event_timeout(dev->ep1_wait_queue, + dev->audio_parm_answer >= 0, HZ)) + return -EPIPE; + + if (dev->audio_parm_answer != 1) + debug("unable to set the device's audio params\n"); + + return dev->audio_parm_answer == 1 ? 0 : -EINVAL; +} + +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, + int digital, int analog, int erp) +{ + char tmp[3] = { digital, analog, erp }; + return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); +} + +static void setup_card(struct snd_usb_caiaqdev *dev) +{ + int ret; + char val[3]; + + /* device-specific startup specials */ + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): + /* RigKontrol2 - display centered dash ('-') */ + val[0] = 0x00; + val[1] = 0x00; + val[2] = 0x01; + send_command(dev, EP1_CMD_WRITE_IO, val, 3); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + /* Audio Kontrol 1 - make USB-LED stop blinking */ + val[0] = 0x00; + send_command(dev, EP1_CMD_WRITE_IO, val, 1); + break; + } + + ret = snd_usb_caiaq_audio_init(dev); + if (ret < 0) + log("Unable to set up audio system (ret=%d)\n", ret); + + ret = snd_usb_caiaq_midi_init(dev); + if (ret < 0) + log("Unable to set up MIDI system (ret=%d)\n", ret); + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + ret = snd_usb_caiaq_input_init(dev); + if (ret < 0) + log("Unable to set up input system (ret=%d)\n", ret); +#endif + + /* finally, register the card and all its sub-instances */ + ret = snd_card_register(dev->chip.card); + if (ret < 0) { + log("snd_card_register() returned %d\n", ret); + snd_card_free(dev->chip.card); + } +} + +static struct snd_card* create_card(struct usb_device* usb_dev) +{ + int devnum; + struct snd_card *card; + struct snd_usb_caiaqdev *dev; + + for (devnum = 0; devnum < SNDRV_CARDS; devnum++) + if (enable[devnum] && !snd_card_used[devnum]) + break; + + if (devnum >= SNDRV_CARDS) + return NULL; + + card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, + sizeof(struct snd_usb_caiaqdev)); + if (!card) + return NULL; + + dev = caiaqdev(card); + dev->chip.dev = usb_dev; + dev->chip.card = card; + dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor, + usb_dev->descriptor.idProduct); + spin_lock_init(&dev->spinlock); + snd_card_set_dev(card, &usb_dev->dev); + + return card; +} + +static int init_card(struct snd_usb_caiaqdev *dev) +{ + char *c; + struct usb_device *usb_dev = dev->chip.dev; + struct snd_card *card = dev->chip.card; + int err, len; + + if (usb_set_interface(usb_dev, 0, 1) != 0) { + log("can't set alt interface.\n"); + return -EIO; + } + + usb_init_urb(&dev->ep1_in_urb); + usb_init_urb(&dev->midi_out_urb); + + usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, + usb_rcvbulkpipe(usb_dev, 0x1), + dev->ep1_in_buf, EP1_BUFSIZE, + usb_ep1_command_reply_dispatch, dev); + + usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, + usb_sndbulkpipe(usb_dev, 0x1), + dev->midi_out_buf, EP1_BUFSIZE, + snd_usb_caiaq_midi_output_done, dev); + + init_waitqueue_head(&dev->ep1_wait_queue); + init_waitqueue_head(&dev->prepare_wait_queue); + + if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) + return -EIO; + + err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); + if (err) + return err; + + if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ)) + return -ENODEV; + + usb_string(usb_dev, usb_dev->descriptor.iManufacturer, + dev->vendor_name, CAIAQ_USB_STR_LEN); + + usb_string(usb_dev, usb_dev->descriptor.iProduct, + dev->product_name, CAIAQ_USB_STR_LEN); + + usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, + dev->serial, CAIAQ_USB_STR_LEN); + + /* terminate serial string at first white space occurence */ + c = strchr(dev->serial, ' '); + if (c) + *c = '\0'; + + strcpy(card->driver, MODNAME); + strcpy(card->shortname, dev->product_name); + + len = snprintf(card->longname, sizeof(card->longname), + "%s %s (serial %s, ", + dev->vendor_name, dev->product_name, dev->serial); + + if (len < sizeof(card->longname) - 2) + len += usb_make_path(usb_dev, card->longname + len, + sizeof(card->longname) - len); + + card->longname[len++] = ')'; + card->longname[len] = '\0'; + setup_card(dev); + return 0; +} + +static int snd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int ret; + struct snd_card *card; + struct usb_device *device = interface_to_usbdev(intf); + + card = create_card(device); + + if (!card) + return -ENOMEM; + + dev_set_drvdata(&intf->dev, card); + ret = init_card(caiaqdev(card)); + if (ret < 0) { + log("unable to init card! (ret=%d)\n", ret); + snd_card_free(card); + return ret; + } + + return 0; +} + +static void snd_disconnect(struct usb_interface *intf) +{ + struct snd_usb_caiaqdev *dev; + struct snd_card *card = dev_get_drvdata(&intf->dev); + + debug("snd_disconnect(%p)\n", intf); + + if (!card) + return; + + dev = caiaqdev(card); + snd_card_disconnect(card); + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + snd_usb_caiaq_input_free(dev); +#endif + snd_usb_caiaq_audio_free(dev); + + usb_kill_urb(&dev->ep1_in_urb); + usb_kill_urb(&dev->midi_out_urb); + + snd_card_free(card); + usb_reset_device(interface_to_usbdev(intf)); +} + + +MODULE_DEVICE_TABLE(usb, snd_usb_id_table); +static struct usb_driver snd_usb_driver = { + .name = MODNAME, + .probe = snd_probe, + .disconnect = snd_disconnect, + .id_table = snd_usb_id_table, +}; + +static int __init snd_module_init(void) +{ + return usb_register(&snd_usb_driver); +} + +static void __exit snd_module_exit(void) +{ + usb_deregister(&snd_usb_driver); +} + +module_init(snd_module_init) +module_exit(snd_module_exit) + diff --git a/trunk/sound/usb/caiaq/caiaq-device.h b/trunk/sound/usb/caiaq/caiaq-device.h new file mode 100644 index 000000000000..088d5ec241f3 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-device.h @@ -0,0 +1,116 @@ +#ifndef CAIAQ_DEVICE_H +#define CAIAQ_DEVICE_H + +#include "../usbaudio.h" + +#define USB_VID_NATIVEINSTRUMENTS 0x17cc + +#define USB_PID_RIGKONTROL2 0x1969 +#define USB_PID_KORECONTROLLER 0x4711 +#define USB_PID_AK1 0x0815 +#define USB_PID_AUDIO8DJ 0x1978 + +#define EP1_BUFSIZE 64 +#define CAIAQ_USB_STR_LEN 0xff +#define MAX_STREAMS 32 + +//#define SND_USB_CAIAQ_DEBUG + +#define MODNAME "snd-usb-caiaq" +#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x) + +#ifdef SND_USB_CAIAQ_DEBUG +#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x) +#else +#define debug(x...) do { } while(0) +#endif + +#define EP1_CMD_GET_DEVICE_INFO 0x1 +#define EP1_CMD_READ_ERP 0x2 +#define EP1_CMD_READ_ANALOG 0x3 +#define EP1_CMD_READ_IO 0x4 +#define EP1_CMD_WRITE_IO 0x5 +#define EP1_CMD_MIDI_READ 0x6 +#define EP1_CMD_MIDI_WRITE 0x7 +#define EP1_CMD_AUDIO_PARAMS 0x9 +#define EP1_CMD_AUTO_MSG 0xb + +struct caiaq_device_spec { + unsigned short fw_version; + unsigned char hw_subtype; + unsigned char num_erp; + unsigned char num_analog_in; + unsigned char num_digital_in; + unsigned char num_digital_out; + unsigned char num_analog_audio_out; + unsigned char num_analog_audio_in; + unsigned char num_digital_audio_out; + unsigned char num_digital_audio_in; + unsigned char num_midi_out; + unsigned char num_midi_in; + unsigned char data_alignment; +} __attribute__ ((packed)); + +struct snd_usb_caiaq_cb_info; + +struct snd_usb_caiaqdev { + struct snd_usb_audio chip; + + struct urb ep1_in_urb; + struct urb midi_out_urb; + struct urb **data_urbs_in; + struct urb **data_urbs_out; + struct snd_usb_caiaq_cb_info *data_cb_info; + + unsigned char ep1_in_buf[EP1_BUFSIZE]; + unsigned char ep1_out_buf[EP1_BUFSIZE]; + unsigned char midi_out_buf[EP1_BUFSIZE]; + + struct caiaq_device_spec spec; + spinlock_t spinlock; + wait_queue_head_t ep1_wait_queue; + wait_queue_head_t prepare_wait_queue; + int spec_received, audio_parm_answer; + + char vendor_name[CAIAQ_USB_STR_LEN]; + char product_name[CAIAQ_USB_STR_LEN]; + char serial[CAIAQ_USB_STR_LEN]; + + int n_streams, n_audio_in, n_audio_out; + int streaming, first_packet, output_running; + int audio_in_buf_pos[MAX_STREAMS]; + int audio_out_buf_pos[MAX_STREAMS]; + int period_in_count[MAX_STREAMS]; + int period_out_count[MAX_STREAMS]; + int input_panic, output_panic; + char *audio_in_buf, *audio_out_buf; + unsigned int samplerates; + + struct snd_pcm_substream *sub_playback[MAX_STREAMS]; + struct snd_pcm_substream *sub_capture[MAX_STREAMS]; + + /* Linux input */ +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + struct input_dev *input_dev; +#endif + + /* ALSA */ + struct snd_pcm *pcm; + struct snd_pcm_hardware pcm_info; + struct snd_rawmidi *rmidi; + struct snd_rawmidi_substream *midi_receive_substream; + struct snd_rawmidi_substream *midi_out_substream; +}; + +struct snd_usb_caiaq_cb_info { + struct snd_usb_caiaqdev *dev; + int index; +}; + +#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data) + +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp); +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp); + + +#endif /* CAIAQ_DEVICE_H */ diff --git a/trunk/sound/usb/caiaq/caiaq-input.c b/trunk/sound/usb/caiaq/caiaq-input.c new file mode 100644 index 000000000000..3acd12db6952 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-input.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caiaq-device.h" +#include "caiaq-input.h" + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + +static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; +static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7 }; + +#define DEG90 (range/2) +#define DEG180 (range) +#define DEG270 (DEG90 + DEG180) +#define DEG360 (DEG180 * 2) +#define HIGH_PEAK (268) +#define LOW_PEAK (-7) + +/* some of these devices have endless rotation potentiometers + * built in which use two tapers, 90 degrees phase shifted. + * this algorithm decodes them to one single value, ranging + * from 0 to 999 */ +static unsigned int decode_erp(unsigned char a, unsigned char b) +{ + int weight_a, weight_b; + int pos_a, pos_b; + int ret; + int range = HIGH_PEAK - LOW_PEAK; + int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; + + weight_b = abs(mid_value-a) - (range/2 - 100)/2; + + if (weight_b < 0) + weight_b = 0; + + if (weight_b > 100) + weight_b = 100; + + weight_a = 100 - weight_b; + + if (a < mid_value) { + /* 0..90 and 270..360 degrees */ + pos_b = b - LOW_PEAK + DEG270; + if (pos_b >= DEG360) + pos_b -= DEG360; + } else + /* 90..270 degrees */ + pos_b = HIGH_PEAK - b + DEG90; + + + if (b > mid_value) + /* 0..180 degrees */ + pos_a = a - LOW_PEAK; + else + /* 180..360 degrees */ + pos_a = HIGH_PEAK - a + DEG180; + + /* interpolate both slider values, depending on weight factors */ + /* 0..99 x DEG360 */ + ret = pos_a * weight_a + pos_b * weight_b; + + /* normalize to 0..999 */ + ret *= 10; + ret /= DEG360; + + if (ret < 0) + ret += 1000; + + if (ret >= 1000) + ret -= 1000; + + return ret; +} + +#undef DEG90 +#undef DEG180 +#undef DEG270 +#undef DEG360 +#undef HIGH_PEAK +#undef LOW_PEAK + + +static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, + const char *buf, unsigned int len) +{ + switch(dev->input_dev->id.product) { + case USB_PID_RIGKONTROL2: + input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]); + input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]); + input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]); + input_sync(dev->input_dev); + break; + } +} + +static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, + const char *buf, unsigned int len) +{ + int i; + + switch(dev->input_dev->id.product) { + case USB_PID_AK1: + i = decode_erp(buf[0], buf[1]); + input_report_abs(dev->input_dev, ABS_X, i); + input_sync(dev->input_dev); + break; + } +} + +static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, + char *buf, unsigned int len) +{ + int i; + unsigned char *keycode = dev->input_dev->keycode; + + if (!keycode) + return; + + if (dev->input_dev->id.product == USB_PID_RIGKONTROL2) + for (i=0; iinput_dev->keycodemax) && (i < len); i++) + input_report_key(dev->input_dev, keycode[i], + buf[i/8] & (1 << (i%8))); + + input_sync(dev->input_dev); +} + +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, + char *buf, + unsigned int len) +{ + if (!dev->input_dev || (len < 1)) + return; + + switch (buf[0]) { + case EP1_CMD_READ_ANALOG: + snd_caiaq_input_read_analog(dev, buf+1, len-1); + break; + case EP1_CMD_READ_ERP: + snd_caiaq_input_read_erp(dev, buf+1, len-1); + break; + case EP1_CMD_READ_IO: + snd_caiaq_input_read_io(dev, buf+1, len-1); + break; + } +} + +int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) +{ + struct usb_device *usb_dev = dev->chip.dev; + struct input_dev *input; + int i, ret; + + input = input_allocate_device(); + if (!input) + return -ENOMEM; + + input->name = dev->product_name; + input->id.bustype = BUS_USB; + input->id.vendor = usb_dev->descriptor.idVendor; + input->id.product = usb_dev->descriptor.idProduct; + input->id.version = usb_dev->descriptor.bcdDevice; + + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); + input->keycode = keycode_rk2; + input->keycodesize = sizeof(char); + input->keycodemax = ARRAY_SIZE(keycode_rk2); + for (i=0; ikeybit); + + input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); + snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X); + input->keycode = keycode_ak1; + input->keycodesize = sizeof(char); + input->keycodemax = ARRAY_SIZE(keycode_ak1); + for (i=0; ikeybit); + + input_set_abs_params(input, ABS_X, 0, 999, 0, 10); + snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); + break; + default: + /* no input methods supported on this device */ + input_free_device(input); + return 0; + } + + ret = input_register_device(input); + if (ret < 0) { + input_free_device(input); + return ret; + } + + dev->input_dev = input; + return 0; +} + +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) +{ + if (!dev || !dev->input_dev) + return; + + input_unregister_device(dev->input_dev); + input_free_device(dev->input_dev); + dev->input_dev = NULL; +} + +#endif /* CONFIG_SND_USB_CAIAQ_INPUT */ + diff --git a/trunk/sound/usb/caiaq/caiaq-input.h b/trunk/sound/usb/caiaq/caiaq-input.h new file mode 100644 index 000000000000..ced535577864 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-input.h @@ -0,0 +1,8 @@ +#ifndef CAIAQ_INPUT_H +#define CAIAQ_INPUT_H + +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len); +int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev); + +#endif diff --git a/trunk/sound/usb/caiaq/caiaq-midi.c b/trunk/sound/usb/caiaq/caiaq-midi.c new file mode 100644 index 000000000000..793ca20ce349 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-midi.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "caiaq-device.h" +#include "caiaq-midi.h" + + +static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) +{ + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; + + if (!dev) + return; + + dev->midi_receive_substream = up ? substream : NULL; +} + + +static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, + struct snd_rawmidi_substream *substream) +{ + int len, ret; + + dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; + dev->midi_out_buf[1] = 0; /* port */ + len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3); + + if (len <= 0) + return; + + dev->midi_out_buf[2] = len; + dev->midi_out_urb.transfer_buffer_length = len+3; + + ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); + if (ret < 0) + log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n", + substream, ret); +} + +static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) +{ + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; + + if (dev->midi_out_substream != NULL) + return; + + if (!up) { + dev->midi_out_substream = NULL; + return; + } + + dev->midi_out_substream = substream; + snd_usb_caiaq_midi_send(dev, substream); +} + + +static struct snd_rawmidi_ops snd_usb_caiaq_midi_output = +{ + .open = snd_usb_caiaq_midi_output_open, + .close = snd_usb_caiaq_midi_output_close, + .trigger = snd_usb_caiaq_midi_output_trigger, +}; + +static struct snd_rawmidi_ops snd_usb_caiaq_midi_input = +{ + .open = snd_usb_caiaq_midi_input_open, + .close = snd_usb_caiaq_midi_input_close, + .trigger = snd_usb_caiaq_midi_input_trigger, +}; + +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, + int port, const char *buf, int len) +{ + if (!dev->midi_receive_substream) + return; + + snd_rawmidi_receive(dev->midi_receive_substream, buf, len); +} + +int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) +{ + int ret; + struct snd_rawmidi *rmidi; + + ret = snd_rawmidi_new(device->chip.card, device->product_name, 0, + device->spec.num_midi_out, + device->spec.num_midi_in, + &rmidi); + + if (ret < 0) + return ret; + + strcpy(rmidi->name, device->product_name); + + rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; + rmidi->private_data = device; + + if (device->spec.num_midi_out > 0) { + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_usb_caiaq_midi_output); + } + + if (device->spec.num_midi_in > 0) { + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_usb_caiaq_midi_input); + } + + device->rmidi = rmidi; + + return 0; +} + +void snd_usb_caiaq_midi_output_done(struct urb* urb) +{ + struct snd_usb_caiaqdev *dev = urb->context; + char *buf = urb->transfer_buffer; + + if (urb->status != 0) + return; + + if (!dev->midi_out_substream) + return; + + snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]); + dev->midi_out_substream = NULL; + snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); +} + diff --git a/trunk/sound/usb/caiaq/caiaq-midi.h b/trunk/sound/usb/caiaq/caiaq-midi.h new file mode 100644 index 000000000000..9d16db027fc3 --- /dev/null +++ b/trunk/sound/usb/caiaq/caiaq-midi.h @@ -0,0 +1,8 @@ +#ifndef CAIAQ_MIDI_H +#define CAIAQ_MIDI_H + +int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); +void snd_usb_caiaq_midi_output_done(struct urb* urb); + +#endif /* CAIAQ_MIDI_H */ diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index b6d886373bb0..8ebc1adb5ed9 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -1878,6 +1878,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre } /* set the period time minimum 1ms */ + /* FIXME: high-speed mode allows 125us minimum period, but many parts + * in the current code assume the 1ms period. + */ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000 * MIN_PACKS_URB, /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index 24f5a26c5f0c..99295f9b7691 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -1,7 +1,7 @@ /* * usbmidi.c - ALSA USB MIDI driver * - * Copyright (c) 2002-2005 Clemens Ladisch + * Copyright (c) 2002-2007 Clemens Ladisch * All rights reserved. * * Based on the OSS usb-midi driver by NAGANO Daisuke, @@ -145,6 +145,7 @@ struct snd_usb_midi_in_endpoint { struct urb* urb; struct usbmidi_in_port { struct snd_rawmidi_substream *substream; + u8 running_status_length; } ports[0x10]; u8 seen_f5; u8 error_resubmit; @@ -365,6 +366,46 @@ static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep, } } +/* + * Buggy M-Audio device: running status on input results in a packet that has + * the data bytes but not the status byte and that is marked with CIN 4. + */ +static void snd_usbmidi_maudio_broken_running_status_input( + struct snd_usb_midi_in_endpoint* ep, + uint8_t* buffer, int buffer_length) +{ + int i; + + for (i = 0; i + 3 < buffer_length; i += 4) + if (buffer[i] != 0) { + int cable = buffer[i] >> 4; + u8 cin = buffer[i] & 0x0f; + struct usbmidi_in_port *port = &ep->ports[cable]; + int length; + + length = snd_usbmidi_cin_length[cin]; + if (cin == 0xf && buffer[i + 1] >= 0xf8) + ; /* realtime msg: no running status change */ + else if (cin >= 0x8 && cin <= 0xe) + /* channel msg */ + port->running_status_length = length - 1; + else if (cin == 0x4 && + port->running_status_length != 0 && + buffer[i + 1] < 0x80) + /* CIN 4 that is not a SysEx */ + length = port->running_status_length; + else + /* + * All other msgs cannot begin running status. + * (A channel msg sent as two or three CIN 0xF + * packets could in theory, but this device + * doesn't use this format.) + */ + port->running_status_length = 0; + snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); + } +} + /* * Adds one USB MIDI packet to the output buffer. */ @@ -525,6 +566,12 @@ static struct usb_protocol_ops snd_usbmidi_midiman_ops = { .output_packet = snd_usbmidi_output_midiman_packet, }; +static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = { + .input = snd_usbmidi_maudio_broken_running_status_input, + .output = snd_usbmidi_standard_output, + .output_packet = snd_usbmidi_output_standard_packet, +}; + /* * Novation USB MIDI protocol: number of data bytes is in the first byte * (when receiving) (+1!) or in the second byte (when sending); data begins @@ -918,7 +965,11 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, } /* we never use interrupt output pipes */ pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); - ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); + if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ + /* FIXME: we need more URBs to get reasonable bandwidth here: */ + ep->max_transfer = 4; + else + ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, GFP_KERNEL, &ep->urb->transfer_dma); if (!buffer) { @@ -1606,6 +1657,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { case QUIRK_MIDI_STANDARD_INTERFACE: err = snd_usbmidi_get_ms_info(umidi, endpoints); + if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ + umidi->usb_protocol_ops = + &snd_usbmidi_maudio_broken_running_status_ops; break; case QUIRK_MIDI_FIXED_ENDPOINT: memcpy(&endpoints[0], quirk->data, diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index 858262068f4f..8fcbe93b2589 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -39,6 +39,29 @@ .idProduct = prod, \ .bInterfaceClass = USB_CLASS_VENDOR_SPEC +/* + * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface + * class matches do not take effect without an explicit ID match. + */ +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x08f0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL +}, +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x08f6, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL +}, + /* * Yamaha devices */